func seekElse(s *scanner.Scanner) error { ifDepth := 0 loop: for { tok := s.Scan() switch tok { case token.ENDOFSCRIPT: return errors.New("Unclosed IF Statements") case token.IF: ifDepth++ case token.ENDIF: if ifDepth == 0 { break loop } else { ifDepth-- } case token.ELSE: if ifDepth == 0 { break loop } } } return nil }
func BenchmarkNops(b *testing.B) { script, _ := hex.DecodeString("61616161616161616161") s := new(scanner.Scanner) for i := 0; i < b.N; i++ { s.Init(script, nil) Parse(s) } }
func BenchmarkStandardTransactionToBitcoinAddress(b *testing.B) { script, _ := hex.DecodeString("76A91489ABCDEFABBAABBAABBAABBAABBAABBAABBAABBA88AC") s := new(scanner.Scanner) for i := 0; i < b.N; i++ { s.Init(script, nil) Parse(s) } }
func TestStandardTransactionToBitcoinAddressFromScanner(t *testing.T) { script, _ := hex.DecodeString("76A91489ABCDEFABBAABBAABBAABBAABBAABBAABBAABBA88AC") s := new(scanner.Scanner) s.Init(script, nil) compiled, _ := Compile(s) if !bytes.Equal(compiled, script) { t.Errorf("Failed") } }
func TestStandardTransactionToBitcoinAddressScanner(t *testing.T) { script, _ := hex.DecodeString("76A91489ABCDEFABBAABBAABBAABBAABBAABBAABBAABBA88AC") checkData, _ := hex.DecodeString("89ABCDEFABBAABBAABBAABBAABBAABBAABBAABBA") s := new(scanner.Scanner) errorReported := false s.Init(script, func(pos int, msg string) { errorReported = true }) tree, err := Parse(s) if err != nil { t.Errorf("Failed %v", err) } root := new(SimpleBlock) root.NodeList = []Node{ &Operation{ ParentBlock: root, OpCode: opcode.DUP, }, &Operation{ ParentBlock: root, OpCode: opcode.HASH160, }, &Data{ ParentBlock: root, Value: checkData, }, &Operation{ ParentBlock: root, OpCode: opcode.EQUALVERIFY, }, &Operation{ ParentBlock: root, OpCode: opcode.CHECKSIG, }, } if !root.Equals(tree) { t.Errorf("AST Mismatch") } }
func (this *Executor) execAst(script []byte) error { s := new(scanner.Scanner) s.Init(script, nil) block, err := ast.Parse(s) if err != nil { return err } err = block.ForEachNode(this) if err != nil { return err } if s.ErrorCount() != 0 { return errors.New("TokenSource reported errors") } return nil }
func (this *Executor) execScanner(script []byte) error { s := new(scanner.Scanner) s.Init(script, nil) ifDepth := 0 loop: for { tok := s.Scan() switch tok { case token.DATA: this.Push(s.Data()) case token.OPERATION: impl := opCodeImpls[s.Op()] if impl == nil { return errors.New("Unknown OpCode - " + s.Op().String()) } err := impl(&this.Context) if err != nil { return err } case token.ENDOFSCRIPT: break loop case token.NUMBER: this.PushNumber(s.Number()) case token.CODESEPARATOR: this.codeSeparatorPos = s.Pos() case token.IF: ifDepth++ top := this.PopBool() if !top { seekElse(s) } case token.NOTIF: ifDepth++ top := this.PopBool() if top { seekElse(s) } case token.ELSE: if ifDepth == 0 { return errors.New("Unexpected EndIf") } ifDepth-- seekEndIf(s) case token.ENDIF: if ifDepth == 0 { return errors.New("Unexpected Else") } ifDepth-- case token.INVALID: return errors.New("Invalid Token") } } if ifDepth != 0 { return errors.New("Unclosed If") } if s.ErrorCount() != 0 { return errors.New("TokenSource reported errors") } return nil }
func Subscriptify(script []byte, sig []byte) ([]byte, error) { s := new(scanner.Scanner) s.Init(script, nil) subscript := make([]byte, 0, len(script)) loop: for { tok := s.Scan() switch tok { case token.DATA: //Suppress the signature if !bytes.Equal(s.Data(), sig) { subscript = append(subscript, s.ByteCode()) subscript = append(subscript, s.Data()...) } case token.CODESEPARATOR: //Remove code separators case token.ENDOFSCRIPT: break loop case token.INVALID: return nil, errors.New("Invalid Token") default: //All other tokens are passed straight through subscript = append(subscript, s.ByteCode()) } } if s.ErrorCount() != 0 { return nil, errors.New("Scanner Errors Occured") } return subscript, nil }