github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/consensus/bcrp/bcrp.go (about) 1 package bcrp 2 3 import ( 4 "bytes" 5 6 "github.com/bytom/bytom/consensus" 7 "github.com/bytom/bytom/errors" 8 "github.com/bytom/bytom/protocol/vm" 9 ) 10 11 const ( 12 // BCRP bytom contract register protocol 13 BCRP = "bcrp" 14 // Version bcrp version 15 Version = 1 16 ) 17 18 // IsBCRPScript checks if a control program is bytom contract register protocol 19 // BCRP script format: OP_FAIL + OP_DATA_4 + "bcrp" + OP_DATA_1 + "1" + {{dynamic_op}} + contract 20 // 0 < len(contract) <= 75 dynamic_op -> OP_DATA_N 21 // 75 <len(contract) < 256 dynamic_op -> OP_PUSHDATA1 22 // 256 <= len(contract) < 65536 dynamic_op -> OP_PUSHDATA2 23 // len(contract) >= 65536 dynamic_op -> OP_PUSHDATA4 24 func IsBCRPScript(prog []byte) bool { 25 inst, err := vm.ParseProgram(prog) 26 if err != nil { 27 return false 28 } 29 30 if len(inst) != 4 { 31 return false 32 } 33 34 if inst[0].Op != vm.OP_FAIL { 35 return false 36 } 37 38 if inst[1].Op != vm.OP_DATA_4 || !bytes.Equal(inst[1].Data, []byte(BCRP)) { 39 return false 40 } 41 42 if inst[2].Op != vm.OP_DATA_1 || !bytes.Equal(inst[2].Data, []byte{byte(Version)}) { 43 return false 44 } 45 46 return len(inst[3].Data) > 0 47 } 48 49 // IsCallContractScript checks if a program is script call contract registered by BCRP 50 // call contract script format: OP_DATA_4 + "bcrp"+ OP_DATA_32 + SHA3-256(contract) 51 func IsCallContractScript(prog []byte) bool { 52 insts, err := vm.ParseProgram(prog) 53 if err != nil { 54 return false 55 } 56 57 if len(insts) != 2 { 58 return false 59 } 60 61 if insts[0].Op != vm.OP_DATA_4 || !bytes.Equal(insts[0].Data, []byte(BCRP)) { 62 return false 63 } 64 65 return insts[1].Op == vm.OP_DATA_32 && len(insts[1].Data) == consensus.BCRPContractHashDataSize 66 } 67 68 // ParseContract parse contract from BCRP script 69 // BCRP script format: OP_FAIL + OP_DATA_4 + "bcrp" + OP_DATA_1 + "1" + {{dynamic_op}} + contract 70 func ParseContract(prog []byte) ([]byte, error) { 71 insts, err := vm.ParseProgram(prog) 72 if err != nil { 73 return nil, err 74 } 75 76 if len(insts) != 4 { 77 return nil, errors.New("unsupport program") 78 } 79 80 return insts[3].Data, nil 81 } 82 83 // ParseContractHash parse contract hash from call BCRP script 84 // call contract script format: OP_DATA_4 + "bcrp"+ OP_DATA_32 + SHA3-256(contract) 85 func ParseContractHash(prog []byte) ([32]byte, error) { 86 insts, err := vm.ParseProgram(prog) 87 if err != nil { 88 return [32]byte{}, err 89 } 90 91 if len(insts) != 2 { 92 return [32]byte{}, errors.New("unsupport program") 93 } 94 95 var hash [32]byte 96 copy(hash[:], insts[1].Data) 97 98 return hash, nil 99 }