6 "github.com/vapor/consensus"
7 "github.com/vapor/protocol/bc"
8 "github.com/vapor/protocol/vm"
9 "github.com/vapor/protocol/vm/vmutil"
12 // IsP2WScript is used to determine whether it is a P2WScript or not
13 func IsP2WScript(prog []byte) bool {
14 return IsP2WPKHScript(prog) || IsP2WSHScript(prog) || IsStraightforward(prog)
17 // IsStraightforward is used to determine whether it is a Straightforward script or not
18 func IsStraightforward(prog []byte) bool {
19 insts, err := vm.ParseProgram(prog)
26 return insts[0].Op == vm.OP_TRUE || insts[0].Op == vm.OP_FAIL
29 // IsP2WPKHScript is used to determine whether it is a P2WPKH script or not
30 func IsP2WPKHScript(prog []byte) bool {
31 insts, err := vm.ParseProgram(prog)
38 if insts[0].Op > vm.OP_16 {
41 return insts[1].Op == vm.OP_DATA_20 && len(insts[1].Data) == consensus.PayToWitnessPubKeyHashDataSize
44 // IsP2WSHScript is used to determine whether it is a P2WSH script or not
45 func IsP2WSHScript(prog []byte) bool {
46 insts, err := vm.ParseProgram(prog)
53 if insts[0].Op > vm.OP_16 {
56 return insts[1].Op == vm.OP_DATA_32 && len(insts[1].Data) == consensus.PayToWitnessScriptHashDataSize
59 // IsP2WMCScript is used to determine whether it is a P2WMC script or not
60 func IsP2WMCScript(prog []byte) bool {
61 insts, err := vm.ParseProgram(prog)
70 if insts[0].Op > vm.OP_16 {
74 if insts[1].Op != vm.OP_DATA_32 || len(insts[1].Data) != 32 {
78 if !(insts[2].IsPushdata() && insts[3].IsPushdata() && insts[4].IsPushdata()) {
82 if _, err = vm.AsInt64(insts[2].Data); err != nil {
86 if _, err = vm.AsInt64(insts[3].Data); err != nil {
89 return insts[5].Op == vm.OP_DATA_32 && len(insts[5].Data) == 32
92 // ConvertP2PKHSigProgram convert standard P2WPKH program into P2PKH program
93 func ConvertP2PKHSigProgram(prog []byte) ([]byte, error) {
94 insts, err := vm.ParseProgram(prog)
98 if insts[0].Op == vm.OP_0 {
99 return vmutil.P2PKHSigProgram(insts[1].Data)
101 return nil, errors.New("unknow P2PKH version number")
104 // ConvertP2SHProgram convert standard P2WSH program into P2SH program
105 func ConvertP2SHProgram(prog []byte) ([]byte, error) {
106 insts, err := vm.ParseProgram(prog)
110 if insts[0].Op == vm.OP_0 {
111 return vmutil.P2SHProgram(insts[1].Data)
113 return nil, errors.New("unknow P2SHP version number")
116 // ConvertP2MCProgram convert standard P2WMC program into P2MC program
117 func ConvertP2MCProgram(prog []byte) ([]byte, error) {
118 magneticContractArgs, err := DecodeP2MCProgram(prog)
122 return vmutil.P2MCProgram(*magneticContractArgs)
125 // DecodeP2MCProgram parse standard P2WMC arguments to magneticContractArgs
126 func DecodeP2MCProgram(prog []byte) (*vmutil.MagneticContractArgs, error) {
127 insts, err := vm.ParseProgram(prog)
132 if len(insts) != 6 || insts[0].Op != vm.OP_0 {
133 return nil, errors.New("invalid P2MC program")
136 magneticContractArgs := &vmutil.MagneticContractArgs{
137 SellerProgram: insts[4].Data,
138 SellerKey: insts[5].Data,
140 requestedAsset := [32]byte{}
141 copy(requestedAsset[:], insts[1].Data)
142 magneticContractArgs.RequestedAsset = bc.NewAssetID(requestedAsset)
144 if magneticContractArgs.RatioMolecule, err = vm.AsInt64(insts[2].Data); err != nil {
148 if magneticContractArgs.RatioDenominator, err = vm.AsInt64(insts[3].Data); err != nil {
151 return magneticContractArgs, nil
154 // GetHashFromStandardProg get hash from standard program
155 func GetHashFromStandardProg(prog []byte) ([]byte, error) {
156 insts, err := vm.ParseProgram(prog)
161 return insts[1].Data, nil