6 "github.com/bytom/bytom/consensus"
7 "github.com/bytom/bytom/errors"
8 "github.com/bytom/bytom/protocol/vm"
12 // BCRP bytom contract register protocol
14 // Version bcrp version
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)
34 if inst[0].Op != vm.OP_FAIL {
38 if inst[1].Op != vm.OP_DATA_4 || !bytes.Equal(inst[1].Data, []byte(BCRP)) {
42 if inst[2].Op != vm.OP_DATA_1 || !bytes.Equal(inst[2].Data, []byte{byte(Version)}) {
46 return len(inst[3].Data) > 0
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)
61 if insts[0].Op != vm.OP_DATA_4 || !bytes.Equal(insts[0].Data, []byte(BCRP)) {
65 return insts[1].Op == vm.OP_DATA_32 && len(insts[1].Data) == consensus.BCRPContractHashDataSize
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)
77 return nil, errors.New("unsupport program")
80 return insts[3].Data, nil
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)
88 return [32]byte{}, err
92 return [32]byte{}, errors.New("unsupport program")
96 copy(hash[:], insts[1].Data)