From 4786a5980b5f8e4cb6972c28b00e86681a40ecc1 Mon Sep 17 00:00:00 2001 From: paladz Date: Tue, 14 Sep 2021 01:45:28 +0800 Subject: [PATCH 01/18] working case for nft contract --- nft/nft.go | 146 +++++++++++++++++++++++++++++++++++++++++++ nft/nft_test.go | 136 ++++++++++++++++++++++++++++++++++++++++ protocol/vm/types.go | 8 ++- 3 files changed, 287 insertions(+), 3 deletions(-) create mode 100644 nft/nft.go create mode 100644 nft/nft_test.go diff --git a/nft/nft.go b/nft/nft.go new file mode 100644 index 000000000..5aff20d94 --- /dev/null +++ b/nft/nft.go @@ -0,0 +1,146 @@ +package nft + +import ( + "github.com/bytom/bytom/protocol/vm" + "github.com/bytom/bytom/protocol/vm/vmutil" +) + +/* + init alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + buy data stack [buyer, payAmount, marginAmount, selecter] + edit data stack [newMarginAsset, newMarginAmount, selecter] +*/ + +func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { + builder := vmutil.NewBuilder() + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [...... selecter] + builder.AddJumpIf(0) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, payAmount, marginAmount] + builder.AddOp(vm.OP_SWAP) + builder.AddOp(vm.OP_DUP) + builder.AddUint64(100) + builder.AddOp(vm.OP_DIV) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, payAmount, platformFee] + builder.AddOp(vm.OP_SWAP) + builder.AddOp(vm.OP_DUP) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, platformFee, payAmount, payAmount] + cpAltStack(builder, 4) + builder.AddOp(vm.OP_MUL) + builder.AddUint64(100) + builder.AddOp(vm.OP_DIV) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, platformFee, payAmount, createrTax] + builder.AddOp(vm.OP_DUP) + builder.AddUint64(2) + builder.AddOp(vm.OP_SWAP) + cpAltStack(builder, 1) + builder.AddUint64(1) + cpAltStack(builder, 5) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, PROGRAM] + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + builder.AddOp(vm.OP_SUB) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, platformFee, payAmount-createrTax] + builder.AddOp(vm.OP_SWAP) + builder.AddOp(vm.OP_DUP) + builder.AddUint64(3) + builder.AddOp(vm.OP_SWAP) + cpAltStack(builder, 1) + builder.AddUint64(1) + builder.AddData(platformScript) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + builder.AddOp(vm.OP_SUB) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, ownerGot] + builder.AddOp(vm.OP_DUP) + cpAltStack(builder, 0) + builder.AddUint64(marginFold) + builder.AddOp(vm.OP_MUL) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, ownerGot, ownerGot, marginAmount*marginFold] + builder.AddOp(vm.OP_GREATERTHANOREQUAL) + builder.AddOp(vm.OP_VERIFY) + cpAltStack(builder, 0) + builder.AddOp(vm.OP_ADD) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, ownerGot+marginAmount] + builder.AddUint64(4) + builder.AddOp(vm.OP_SWAP) + cpAltStack(builder, 1) + builder.AddUint64(1) + cpAltStack(builder, 2) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [buyer, newMarginAmount] + swapAltStack(builder, 1, 2) + swapAltStack(builder, 0, 0) + // alt stack [creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] + // data statck [] + builder.AddJump(1) + + builder.SetJumpTarget(0) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [newMarginAsset, newMarginAmount] + swapAltStack(builder, 1, 1) + swapAltStack(builder, 0, 0) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [] + builder.SetJumpTarget(1) + builder.AddUint64(0) + builder.AddUint64(1) + cpAltStack(builder, 3) + builder.AddUint64(1) + builder.AddOp(vm.OP_PROGRAM) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [0, 1, nftAsset, 1, PROGRAM] + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + builder.AddUint64(1) + cpAltStack(builder, 0) + cpAltStack(builder, 1) + builder.AddUint64(1) + builder.AddOp(vm.OP_PROGRAM) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [1, newMarginAmount, newMarginAsset, 1, PROGRAM] + builder.AddOp(vm.OP_CHECKOUTPUT) + return builder.Build() +} + +func swapAltStack(builder *vmutil.Builder, dataPos, AltPos uint64) { + for i := uint64(0); i <= AltPos; i++ { + builder.AddOp(vm.OP_FROMALTSTACK) + } + + builder.AddOp(vm.OP_DROP) + builder.AddUint64(dataPos + AltPos) + builder.AddOp(vm.OP_ROLL) + + for i := uint64(0); i <= AltPos; i++ { + builder.AddOp(vm.OP_TOALTSTACK) + } +} + +func cpAltStack(builder *vmutil.Builder, pos uint64) { + for i := uint64(0); i <= pos; i++ { + builder.AddOp(vm.OP_FROMALTSTACK) + } + + builder.AddOp(vm.OP_DUP) + + for i := uint64(0); i <= pos; i++ { + builder.AddOp(vm.OP_SWAP) + builder.AddOp(vm.OP_TOALTSTACK) + } +} diff --git a/nft/nft_test.go b/nft/nft_test.go new file mode 100644 index 000000000..e8033cf49 --- /dev/null +++ b/nft/nft_test.go @@ -0,0 +1,136 @@ +package nft + +import ( + "testing" + + "github.com/bytom/bytom/consensus" + "github.com/bytom/bytom/protocol/bc" + "github.com/bytom/bytom/protocol/bc/types" + "github.com/bytom/bytom/protocol/validation" + "github.com/bytom/bytom/protocol/vm" + "github.com/bytom/bytom/testutil" +) + +var ( + marginFold = uint64(10) + taxRate = uint64(10) + anyCanSpendScript = testutil.MustDecodeHexString("51") + platformScript = []byte("platformScript") + createrScript = []byte("createrScript") + nftAsset = testutil.MustDecodeAsset("a0a71c215764e342d10d003be6369baf4145d9c7977f7b8f6bf446e628d8b8b8") + BTC = testutil.MustDecodeAsset("bda946b3110fa46fd94346ce3f05f0760f1b9de72e238835bc4d19f9d64f1742") + ETH = testutil.MustDecodeAsset("78de44ffa1bce37b757c9eae8925b5f199dc4621b412ef0f3f46168865284a93") + + utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") + ownerScirpt = []byte("ownerScirpt") + buyerScirpt = []byte("buyerScirpt") +) + +// 从2个BTC的押金换成50个ETH的 +func TestEditMargin(t *testing.T) { + contract, err := NewContract(platformScript, marginFold) + if err != nil { + t.Fatal(err) + } + + oldStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + BTC.Bytes(), + vm.Uint64Bytes(200000000), + } + + newStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + ETH.Bytes(), + vm.Uint64Bytes(50000000000), + } + + arguments := [][]byte{ + ETH.Bytes(), + vm.Uint64Bytes(50000000000), + vm.Uint64Bytes(1), + } + + tx := types.NewTx(types.TxData{ + Version: 1, + SerializedSize: 10000, + Inputs: []*types.TxInput{ + types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), + types.NewSpendInput(arguments, utxoSourceID, BTC, 200000000, 1, contract, oldStateData), + types.NewSpendInput(nil, utxoSourceID, ETH, 50000000000, 2, anyCanSpendScript, nil), + types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), + }, + Outputs: []*types.TxOutput{ + types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), + types.NewOriginalTxOutput(ETH, 50000000000, contract, newStateData), + types.NewOriginalTxOutput(BTC, 200000000, ownerScirpt, newStateData), + }, + }) + + _, err = validation.ValidateTx(tx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{}}, func(prog []byte) ([]byte, error) { return nil, nil }) + if err != nil { + t.Fatal(err) + } +} + +// 10个ETH质押被120个ETH买走, 然后被质押15个ETH +func TestBuy(t *testing.T) { + contract, err := NewContract(platformScript, marginFold) + if err != nil { + t.Fatal(err) + } + + oldStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + ETH.Bytes(), + vm.Uint64Bytes(10000000000), + } + + newStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + buyerScirpt, + ETH.Bytes(), + vm.Uint64Bytes(15000000000), + } + + arguments := [][]byte{ + buyerScirpt, + vm.Uint64Bytes(120000000000), + vm.Uint64Bytes(15000000000), + vm.Uint64Bytes(0), + } + + tx := types.NewTx(types.TxData{ + Version: 1, + SerializedSize: 10000, + Inputs: []*types.TxInput{ + types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), + types.NewSpendInput(arguments, utxoSourceID, ETH, 10000000000, 1, contract, oldStateData), + types.NewSpendInput(nil, utxoSourceID, ETH, 135000000000, 2, anyCanSpendScript, nil), + types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), + }, + Outputs: []*types.TxOutput{ + types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), + types.NewOriginalTxOutput(ETH, 15000000000, contract, newStateData), + types.NewOriginalTxOutput(ETH, 12000000000, createrScript, oldStateData), + types.NewOriginalTxOutput(ETH, 1200000000, platformScript, oldStateData), + types.NewOriginalTxOutput(ETH, 116800000000, ownerScirpt, oldStateData), + }, + }) + + _, err = validation.ValidateTx(tx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{}}, func(prog []byte) ([]byte, error) { return nil, nil }) + if err != nil { + t.Fatal(err) + } +} diff --git a/protocol/vm/types.go b/protocol/vm/types.go index 99b0c98d8..5d51a0d6b 100644 --- a/protocol/vm/types.go +++ b/protocol/vm/types.go @@ -62,9 +62,11 @@ func bigIntInt64(n *uint256.Int) (int64, error) { // reverse []byte. func reverse(b []byte) []byte { - for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 { - b[i], b[j] = b[j], b[i] + r := make([]byte, len(b)) + copy(r, b) + for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 { + r[i], r[j] = r[j], r[i] } - return b + return r } From f16846b2b22918457170010ad5ebd241da8821ab Mon Sep 17 00:00:00 2001 From: paladz Date: Thu, 16 Sep 2021 19:34:38 +0800 Subject: [PATCH 02/18] add offer contract --- nft/nft.go | 18 +++++++++++++++ nft/nft_test.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/nft/nft.go b/nft/nft.go index 5aff20d94..b27004f0f 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -118,6 +118,24 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { return builder.Build() } +func NewOffer(nftContract []byte) ([]byte, error) { + builder := vmutil.NewBuilder() + builder.AddUint64(0) + builder.AddUint64(1) + cpAltStack(builder, 3) + builder.AddUint64(1) + builder.AddData(nftContract) + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + builder.AddUint64(1) + cpAltStack(builder, 0) + cpAltStack(builder, 1) + builder.AddUint64(1) + builder.AddData(nftContract) + builder.AddOp(vm.OP_CHECKOUTPUT) + return builder.Build() +} + func swapAltStack(builder *vmutil.Builder, dataPos, AltPos uint64) { for i := uint64(0); i <= AltPos; i++ { builder.AddOp(vm.OP_FROMALTSTACK) diff --git a/nft/nft_test.go b/nft/nft_test.go index e8033cf49..1655766c0 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -134,3 +134,64 @@ func TestBuy(t *testing.T) { t.Fatal(err) } } + +// 10个ETH质押被120个ETH买走, 然后被质押15个ETH +func TestOfferBuy(t *testing.T) { + contract, err := NewContract(platformScript, marginFold) + if err != nil { + t.Fatal(err) + } + + offer, err := NewOffer(contract) + if err != nil { + t.Fatal(err) + } + + oldStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + ETH.Bytes(), + vm.Uint64Bytes(10000000000), + } + + newStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + buyerScirpt, + ETH.Bytes(), + vm.Uint64Bytes(15000000000), + } + + arguments := [][]byte{ + buyerScirpt, + vm.Uint64Bytes(120000000000), + vm.Uint64Bytes(15000000000), + vm.Uint64Bytes(0), + } + + tx := types.NewTx(types.TxData{ + Version: 1, + SerializedSize: 10000, + Inputs: []*types.TxInput{ + types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), + types.NewSpendInput(arguments, utxoSourceID, ETH, 10000000000, 1, contract, oldStateData), + types.NewSpendInput(nil, utxoSourceID, ETH, 135000000000, 2, offer, newStateData), + types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), + }, + Outputs: []*types.TxOutput{ + types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), + types.NewOriginalTxOutput(ETH, 15000000000, contract, newStateData), + types.NewOriginalTxOutput(ETH, 12000000000, createrScript, oldStateData), + types.NewOriginalTxOutput(ETH, 1200000000, platformScript, oldStateData), + types.NewOriginalTxOutput(ETH, 116800000000, ownerScirpt, oldStateData), + }, + }) + + _, err = validation.ValidateTx(tx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{}}, func(prog []byte) ([]byte, error) { return nil, nil }) + if err != nil { + t.Fatal(err) + } +} From 8c2c62565dde71cfadbce634900ad3b3ceb16cc5 Mon Sep 17 00:00:00 2001 From: paladz Date: Thu, 16 Sep 2021 19:50:19 +0800 Subject: [PATCH 03/18] buy swap margin --- nft/nft.go | 27 +++++++++++----------- nft/nft_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 13 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index b27004f0f..e1c022d7f 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -17,23 +17,23 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { // data statck [...... selecter] builder.AddJumpIf(0) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, payAmount, marginAmount] + // data statck [marginAsset, buyer, payAmount, marginAmount] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) builder.AddUint64(100) builder.AddOp(vm.OP_DIV) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, payAmount, platformFee] + // data statck [marginAsset, buyer, newMarginAmount, payAmount, platformFee] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, platformFee, payAmount, payAmount] + // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, payAmount] cpAltStack(builder, 4) builder.AddOp(vm.OP_MUL) builder.AddUint64(100) builder.AddOp(vm.OP_DIV) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, platformFee, payAmount, createrTax] + // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax] builder.AddOp(vm.OP_DUP) builder.AddUint64(2) builder.AddOp(vm.OP_SWAP) @@ -41,12 +41,12 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.AddUint64(1) cpAltStack(builder, 5) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, PROGRAM] + // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, platformFee, payAmount-createrTax] + // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount-createrTax] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) builder.AddUint64(3) @@ -55,39 +55,40 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.AddUint64(1) builder.AddData(platformScript) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] + // data statck [marginAsset, buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, ownerGot] + // data statck [marginAsset, buyer, newMarginAmount, ownerGot] builder.AddOp(vm.OP_DUP) cpAltStack(builder, 0) builder.AddUint64(marginFold) builder.AddOp(vm.OP_MUL) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, ownerGot, ownerGot, marginAmount*marginFold] + // data statck [marginAsset, buyer, newMarginAmount, ownerGot, ownerGot, marginAmount*marginFold] builder.AddOp(vm.OP_GREATERTHANOREQUAL) builder.AddOp(vm.OP_VERIFY) cpAltStack(builder, 0) builder.AddOp(vm.OP_ADD) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, ownerGot+marginAmount] + // data statck [marginAsset, buyer, newMarginAmount, ownerGot+marginAmount] builder.AddUint64(4) builder.AddOp(vm.OP_SWAP) cpAltStack(builder, 1) builder.AddUint64(1) cpAltStack(builder, 2) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] + // data statck [marginAsset, buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [buyer, newMarginAmount] + // data statck [marginAsset, buyer, newMarginAmount] swapAltStack(builder, 1, 2) swapAltStack(builder, 0, 0) // alt stack [creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] - // data statck [] + // data statck [marginAsset] + swapAltStack(builder, 0, 1) builder.AddJump(1) builder.SetJumpTarget(0) diff --git a/nft/nft_test.go b/nft/nft_test.go index 1655766c0..18dbc2890 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -105,6 +105,7 @@ func TestBuy(t *testing.T) { } arguments := [][]byte{ + ETH.Bytes(), buyerScirpt, vm.Uint64Bytes(120000000000), vm.Uint64Bytes(15000000000), @@ -135,6 +136,64 @@ func TestBuy(t *testing.T) { } } +// 10个ETH质押被120个ETH买走, 然后被质押2个BTC +func TestBuySwapMargin(t *testing.T) { + contract, err := NewContract(platformScript, marginFold) + if err != nil { + t.Fatal(err) + } + + oldStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + ETH.Bytes(), + vm.Uint64Bytes(10000000000), + } + + newStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + buyerScirpt, + BTC.Bytes(), + vm.Uint64Bytes(200000000), + } + + arguments := [][]byte{ + BTC.Bytes(), + buyerScirpt, + vm.Uint64Bytes(120000000000), + vm.Uint64Bytes(200000000), + vm.Uint64Bytes(0), + } + + tx := types.NewTx(types.TxData{ + Version: 1, + SerializedSize: 10000, + Inputs: []*types.TxInput{ + types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), + types.NewSpendInput(arguments, utxoSourceID, ETH, 10000000000, 1, contract, oldStateData), + types.NewSpendInput(nil, utxoSourceID, ETH, 120000000000, 2, anyCanSpendScript, nil), + types.NewSpendInput(nil, utxoSourceID, BTC, 200000000, 3, anyCanSpendScript, nil), + types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), + }, + Outputs: []*types.TxOutput{ + types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), + types.NewOriginalTxOutput(BTC, 200000000, contract, newStateData), + types.NewOriginalTxOutput(ETH, 12000000000, createrScript, oldStateData), + types.NewOriginalTxOutput(ETH, 1200000000, platformScript, oldStateData), + types.NewOriginalTxOutput(ETH, 116800000000, ownerScirpt, oldStateData), + }, + }) + + _, err = validation.ValidateTx(tx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{}}, func(prog []byte) ([]byte, error) { return nil, nil }) + if err != nil { + t.Fatal(err) + } +} + // 10个ETH质押被120个ETH买走, 然后被质押15个ETH func TestOfferBuy(t *testing.T) { contract, err := NewContract(platformScript, marginFold) @@ -166,6 +225,7 @@ func TestOfferBuy(t *testing.T) { } arguments := [][]byte{ + ETH.Bytes(), buyerScirpt, vm.Uint64Bytes(120000000000), vm.Uint64Bytes(15000000000), From 027425dab4795a350ea0934aa6a8a62049e5fbb9 Mon Sep 17 00:00:00 2001 From: paladz Date: Thu, 23 Sep 2021 11:40:30 +0800 Subject: [PATCH 04/18] edit add margin --- nft/nft.go | 3 +-- nft/nft_test.go | 14 ++++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index e1c022d7f..4943485c8 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -93,8 +93,7 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.SetJumpTarget(0) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [newMarginAsset, newMarginAmount] - swapAltStack(builder, 1, 1) + // data statck [newMarginAmount] swapAltStack(builder, 0, 0) // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [] diff --git a/nft/nft_test.go b/nft/nft_test.go index 18dbc2890..49052f717 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -26,7 +26,7 @@ var ( buyerScirpt = []byte("buyerScirpt") ) -// 从2个BTC的押金换成50个ETH的 +// 从2个BTC的押金换成3个BTC的 func TestEditMargin(t *testing.T) { contract, err := NewContract(platformScript, marginFold) if err != nil { @@ -47,13 +47,12 @@ func TestEditMargin(t *testing.T) { vm.Uint64Bytes(taxRate), nftAsset.Bytes(), ownerScirpt, - ETH.Bytes(), - vm.Uint64Bytes(50000000000), + BTC.Bytes(), + vm.Uint64Bytes(300000000), } arguments := [][]byte{ - ETH.Bytes(), - vm.Uint64Bytes(50000000000), + vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -63,13 +62,12 @@ func TestEditMargin(t *testing.T) { Inputs: []*types.TxInput{ types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), types.NewSpendInput(arguments, utxoSourceID, BTC, 200000000, 1, contract, oldStateData), - types.NewSpendInput(nil, utxoSourceID, ETH, 50000000000, 2, anyCanSpendScript, nil), + types.NewSpendInput(nil, utxoSourceID, BTC, 100000000, 2, anyCanSpendScript, nil), types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), }, Outputs: []*types.TxOutput{ types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), - types.NewOriginalTxOutput(ETH, 50000000000, contract, newStateData), - types.NewOriginalTxOutput(BTC, 200000000, ownerScirpt, newStateData), + types.NewOriginalTxOutput(BTC, 300000000, contract, newStateData), }, }) From 52a8ddf60870b99ac5d3f08b76a981a617fa8e70 Mon Sep 17 00:00:00 2001 From: paladz Date: Thu, 23 Sep 2021 15:53:08 +0800 Subject: [PATCH 05/18] add cancel offer --- nft/nft.go | 5 +++++ nft/nft_test.go | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/nft/nft.go b/nft/nft.go index 4943485c8..e1f800819 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -120,6 +120,10 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { func NewOffer(nftContract []byte) ([]byte, error) { builder := vmutil.NewBuilder() + builder.AddJumpIf(0) + builder.AddUint64(1) + builder.AddJump(1) + builder.SetJumpTarget(0) builder.AddUint64(0) builder.AddUint64(1) cpAltStack(builder, 3) @@ -133,6 +137,7 @@ func NewOffer(nftContract []byte) ([]byte, error) { builder.AddUint64(1) builder.AddData(nftContract) builder.AddOp(vm.OP_CHECKOUTPUT) + builder.SetJumpTarget(1) return builder.Build() } diff --git a/nft/nft_test.go b/nft/nft_test.go index 49052f717..615fc5246 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -236,7 +236,7 @@ func TestOfferBuy(t *testing.T) { Inputs: []*types.TxInput{ types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), types.NewSpendInput(arguments, utxoSourceID, ETH, 10000000000, 1, contract, oldStateData), - types.NewSpendInput(nil, utxoSourceID, ETH, 135000000000, 2, offer, newStateData), + types.NewSpendInput([][]byte{vm.Uint64Bytes(1)}, utxoSourceID, ETH, 135000000000, 2, offer, newStateData), types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), }, Outputs: []*types.TxOutput{ @@ -253,3 +253,45 @@ func TestOfferBuy(t *testing.T) { t.Fatal(err) } } + +func TestCancelOffer(t *testing.T) { + contract, err := NewContract(platformScript, marginFold) + if err != nil { + t.Fatal(err) + } + + offer, err := NewOffer(contract) + if err != nil { + t.Fatal(err) + } + + newStateData := [][]byte{ + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + buyerScirpt, + ETH.Bytes(), + vm.Uint64Bytes(15000000000), + } + + arguments := [][]byte{ + vm.Uint64Bytes(0), + } + + tx := types.NewTx(types.TxData{ + Version: 1, + SerializedSize: 10000, + Inputs: []*types.TxInput{ + types.NewSpendInput(arguments, utxoSourceID, ETH, 135000000000, 2, offer, newStateData), + types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), + }, + Outputs: []*types.TxOutput{ + types.NewOriginalTxOutput(ETH, 135000000000, ownerScirpt, newStateData), + }, + }) + + _, err = validation.ValidateTx(tx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{}}, func(prog []byte) ([]byte, error) { return nil, nil }) + if err != nil { + t.Fatal(err) + } +} From f59ae4755d33eed14d4c8eb3d48bb1ce5f5f43f5 Mon Sep 17 00:00:00 2001 From: paladz Date: Tue, 28 Sep 2021 09:41:01 +0800 Subject: [PATCH 06/18] xx.xx% tax rate --- nft/nft.go | 2 +- nft/nft_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index e1f800819..f14464ad4 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -30,7 +30,7 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, payAmount] cpAltStack(builder, 4) builder.AddOp(vm.OP_MUL) - builder.AddUint64(100) + builder.AddUint64(10000) builder.AddOp(vm.OP_DIV) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax] diff --git a/nft/nft_test.go b/nft/nft_test.go index 615fc5246..ce15a71cc 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -13,7 +13,7 @@ import ( var ( marginFold = uint64(10) - taxRate = uint64(10) + taxRate = uint64(1000) anyCanSpendScript = testutil.MustDecodeHexString("51") platformScript = []byte("platformScript") createrScript = []byte("createrScript") From b954590299a759144891b743e5f45a7c67beb99f Mon Sep 17 00:00:00 2001 From: paladz Date: Wed, 29 Sep 2021 17:03:50 +0800 Subject: [PATCH 07/18] edit contract --- nft/nft.go | 18 +++++++----------- nft/nft_test.go | 35 ++++++++++++++++------------------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index f14464ad4..bed1d2780 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -7,7 +7,7 @@ import ( /* init alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - buy data stack [buyer, payAmount, marginAmount, selecter] + buy data stack [buyer, marginAmount, selecter] edit data stack [newMarginAsset, newMarginAmount, selecter] */ @@ -17,8 +17,12 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { // data statck [...... selecter] builder.AddJumpIf(0) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, payAmount, marginAmount] - builder.AddOp(vm.OP_SWAP) + // data statck [marginAsset, buyer, newMarginAmount] + cpAltStack(builder, 0) + builder.AddUint64(marginFold) + builder.AddOp(vm.OP_MUL) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [marginAsset, buyer, newMarginAmount, payAmount=marginAmount*marginFold] builder.AddOp(vm.OP_DUP) builder.AddUint64(100) builder.AddOp(vm.OP_DIV) @@ -61,14 +65,6 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.AddOp(vm.OP_SUB) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, ownerGot] - builder.AddOp(vm.OP_DUP) - cpAltStack(builder, 0) - builder.AddUint64(marginFold) - builder.AddOp(vm.OP_MUL) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, ownerGot, ownerGot, marginAmount*marginFold] - builder.AddOp(vm.OP_GREATERTHANOREQUAL) - builder.AddOp(vm.OP_VERIFY) cpAltStack(builder, 0) builder.AddOp(vm.OP_ADD) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] diff --git a/nft/nft_test.go b/nft/nft_test.go index ce15a71cc..0f27f1a7a 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -77,8 +77,8 @@ func TestEditMargin(t *testing.T) { } } -// 10个ETH质押被120个ETH买走, 然后被质押15个ETH -func TestBuy(t *testing.T) { +// 10个ETH质押被买走, 然后被质押15个ETH +func TestRegularBuy(t *testing.T) { contract, err := NewContract(platformScript, marginFold) if err != nil { t.Fatal(err) @@ -105,7 +105,6 @@ func TestBuy(t *testing.T) { arguments := [][]byte{ ETH.Bytes(), buyerScirpt, - vm.Uint64Bytes(120000000000), vm.Uint64Bytes(15000000000), vm.Uint64Bytes(0), } @@ -116,15 +115,15 @@ func TestBuy(t *testing.T) { Inputs: []*types.TxInput{ types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), types.NewSpendInput(arguments, utxoSourceID, ETH, 10000000000, 1, contract, oldStateData), - types.NewSpendInput(nil, utxoSourceID, ETH, 135000000000, 2, anyCanSpendScript, nil), + types.NewSpendInput(nil, utxoSourceID, ETH, 115000000000, 2, anyCanSpendScript, nil), types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), }, Outputs: []*types.TxOutput{ types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), types.NewOriginalTxOutput(ETH, 15000000000, contract, newStateData), - types.NewOriginalTxOutput(ETH, 12000000000, createrScript, oldStateData), - types.NewOriginalTxOutput(ETH, 1200000000, platformScript, oldStateData), - types.NewOriginalTxOutput(ETH, 116800000000, ownerScirpt, oldStateData), + types.NewOriginalTxOutput(ETH, 10000000000, createrScript, oldStateData), + types.NewOriginalTxOutput(ETH, 1000000000, platformScript, oldStateData), + types.NewOriginalTxOutput(ETH, 99000000000, ownerScirpt, oldStateData), }, }) @@ -134,7 +133,7 @@ func TestBuy(t *testing.T) { } } -// 10个ETH质押被120个ETH买走, 然后被质押2个BTC +// 10个ETH质押被买走, 然后被质押2个BTC func TestBuySwapMargin(t *testing.T) { contract, err := NewContract(platformScript, marginFold) if err != nil { @@ -162,7 +161,6 @@ func TestBuySwapMargin(t *testing.T) { arguments := [][]byte{ BTC.Bytes(), buyerScirpt, - vm.Uint64Bytes(120000000000), vm.Uint64Bytes(200000000), vm.Uint64Bytes(0), } @@ -173,16 +171,16 @@ func TestBuySwapMargin(t *testing.T) { Inputs: []*types.TxInput{ types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), types.NewSpendInput(arguments, utxoSourceID, ETH, 10000000000, 1, contract, oldStateData), - types.NewSpendInput(nil, utxoSourceID, ETH, 120000000000, 2, anyCanSpendScript, nil), + types.NewSpendInput(nil, utxoSourceID, ETH, 100000000000, 2, anyCanSpendScript, nil), types.NewSpendInput(nil, utxoSourceID, BTC, 200000000, 3, anyCanSpendScript, nil), types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), }, Outputs: []*types.TxOutput{ types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), types.NewOriginalTxOutput(BTC, 200000000, contract, newStateData), - types.NewOriginalTxOutput(ETH, 12000000000, createrScript, oldStateData), - types.NewOriginalTxOutput(ETH, 1200000000, platformScript, oldStateData), - types.NewOriginalTxOutput(ETH, 116800000000, ownerScirpt, oldStateData), + types.NewOriginalTxOutput(ETH, 10000000000, createrScript, oldStateData), + types.NewOriginalTxOutput(ETH, 1000000000, platformScript, oldStateData), + types.NewOriginalTxOutput(ETH, 99000000000, ownerScirpt, oldStateData), }, }) @@ -192,7 +190,7 @@ func TestBuySwapMargin(t *testing.T) { } } -// 10个ETH质押被120个ETH买走, 然后被质押15个ETH +// 10个ETH质押被买走, 然后被质押15个ETH func TestOfferBuy(t *testing.T) { contract, err := NewContract(platformScript, marginFold) if err != nil { @@ -225,7 +223,6 @@ func TestOfferBuy(t *testing.T) { arguments := [][]byte{ ETH.Bytes(), buyerScirpt, - vm.Uint64Bytes(120000000000), vm.Uint64Bytes(15000000000), vm.Uint64Bytes(0), } @@ -236,15 +233,15 @@ func TestOfferBuy(t *testing.T) { Inputs: []*types.TxInput{ types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), types.NewSpendInput(arguments, utxoSourceID, ETH, 10000000000, 1, contract, oldStateData), - types.NewSpendInput([][]byte{vm.Uint64Bytes(1)}, utxoSourceID, ETH, 135000000000, 2, offer, newStateData), + types.NewSpendInput([][]byte{vm.Uint64Bytes(1)}, utxoSourceID, ETH, 115000000000, 2, offer, newStateData), types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), }, Outputs: []*types.TxOutput{ types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), types.NewOriginalTxOutput(ETH, 15000000000, contract, newStateData), - types.NewOriginalTxOutput(ETH, 12000000000, createrScript, oldStateData), - types.NewOriginalTxOutput(ETH, 1200000000, platformScript, oldStateData), - types.NewOriginalTxOutput(ETH, 116800000000, ownerScirpt, oldStateData), + types.NewOriginalTxOutput(ETH, 10000000000, createrScript, oldStateData), + types.NewOriginalTxOutput(ETH, 1000000000, platformScript, oldStateData), + types.NewOriginalTxOutput(ETH, 99000000000, ownerScirpt, oldStateData), }, }) From c3610f1fb05bff099b1ae6773f5d247326d724d0 Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Thu, 21 Oct 2021 01:06:33 +0800 Subject: [PATCH 08/18] add sig for nft contract func --- nft/nft.go | 22 +++++++++++++++++++++- nft/nft_test.go | 6 ++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index bed1d2780..35719d06a 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -89,9 +89,20 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.SetJumpTarget(0) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [newMarginAmount] + // data statck [ownerSig, newMarginAmount] swapAltStack(builder, 0, 0) // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [ownerSig] + cpAltStack(builder, 2) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [ownerSig, owner] + builder.AddOp(vm.OP_TXSIGHASH) + builder.AddOp(vm.OP_SWAP) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [ownerSig, txSigHash, owner] + builder.AddOp(vm.OP_CHECKSIG) + builder.AddOp(vm.OP_VERIFY) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [] builder.SetJumpTarget(1) builder.AddUint64(0) @@ -119,6 +130,14 @@ func NewOffer(nftContract []byte) ([]byte, error) { builder.AddJumpIf(0) builder.AddUint64(1) builder.AddJump(1) + + // need check sig for cancel func + cpAltStack(builder, 2) + builder.AddOp(vm.OP_TXSIGHASH) + builder.AddOp(vm.OP_SWAP) + builder.AddOp(vm.OP_CHECKSIG) + builder.AddOp(vm.OP_VERIFY) + builder.SetJumpTarget(0) builder.AddUint64(0) builder.AddUint64(1) @@ -134,6 +153,7 @@ func NewOffer(nftContract []byte) ([]byte, error) { builder.AddData(nftContract) builder.AddOp(vm.OP_CHECKOUTPUT) builder.SetJumpTarget(1) + return builder.Build() } diff --git a/nft/nft_test.go b/nft/nft_test.go index 0f27f1a7a..554c589e3 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -22,8 +22,8 @@ var ( ETH = testutil.MustDecodeAsset("78de44ffa1bce37b757c9eae8925b5f199dc4621b412ef0f3f46168865284a93") utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") - ownerScirpt = []byte("ownerScirpt") - buyerScirpt = []byte("buyerScirpt") + ownerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("ownerScirpt") + buyerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("buyerScirpt") ) // 从2个BTC的押金换成3个BTC的 @@ -52,6 +52,7 @@ func TestEditMargin(t *testing.T) { } arguments := [][]byte{ + testutil.MustDecodeHexString("6c25b3220df660b06bf17ca881e6a31811fc4f33f78e5c0597a1e29b5d0030d9494bff417a237b907eac5cdce1dc0dfe1f258103dee32fcc84a2dd5e8c614209"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -272,6 +273,7 @@ func TestCancelOffer(t *testing.T) { } arguments := [][]byte{ + testutil.MustDecodeHexString("2dbbae17e2aed7639ba212f46fd28b9ccb122c1a24ebd1a48e2dddcaf675252e9adb7c8fe504fa4aad4d054d87701d93d67c5e62bee9ccdc442a39a207dcd106"), vm.Uint64Bytes(0), } From d8080df6ccff84ee7087364863f36a89482c2d2b Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Fri, 22 Oct 2021 10:53:43 +0800 Subject: [PATCH 09/18] fix pk for sig fix cancel --- nft/nft.go | 89 ++++++++++++++++++++++++------------------------- nft/nft_test.go | 18 +++++++--- 2 files changed, 58 insertions(+), 49 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index 35719d06a..332ec9a83 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -6,120 +6,120 @@ import ( ) /* - init alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + init alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] buy data stack [buyer, marginAmount, selecter] edit data stack [newMarginAsset, newMarginAmount, selecter] */ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder := vmutil.NewBuilder() - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [...... selecter] builder.AddJumpIf(0) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount] - cpAltStack(builder, 0) + cpAltStack(builder, 1) builder.AddUint64(marginFold) builder.AddOp(vm.OP_MUL) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, payAmount=marginAmount*marginFold] builder.AddOp(vm.OP_DUP) builder.AddUint64(100) builder.AddOp(vm.OP_DIV) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, payAmount, platformFee] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, payAmount] - cpAltStack(builder, 4) + cpAltStack(builder, 5) builder.AddOp(vm.OP_MUL) builder.AddUint64(10000) builder.AddOp(vm.OP_DIV) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax] builder.AddOp(vm.OP_DUP) builder.AddUint64(2) builder.AddOp(vm.OP_SWAP) - cpAltStack(builder, 1) + cpAltStack(builder, 2) builder.AddUint64(1) - cpAltStack(builder, 5) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + cpAltStack(builder, 6) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount-createrTax] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) builder.AddUint64(3) builder.AddOp(vm.OP_SWAP) - cpAltStack(builder, 1) + cpAltStack(builder, 2) builder.AddUint64(1) builder.AddData(platformScript) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, ownerGot] - cpAltStack(builder, 0) + cpAltStack(builder, 1) builder.AddOp(vm.OP_ADD) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, ownerGot+marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // data statck [marginAsset, buyer, newMarginAmount, ownerGot+marginAmount, publicKey] builder.AddUint64(4) builder.AddOp(vm.OP_SWAP) - cpAltStack(builder, 1) - builder.AddUint64(1) cpAltStack(builder, 2) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + builder.AddUint64(1) + cpAltStack(builder, 3) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [marginAsset, buyer, newMarginAmount] - swapAltStack(builder, 1, 2) - swapAltStack(builder, 0, 0) - // alt stack [creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] - // data statck [marginAsset] + swapAltStack(builder, 1, 3) swapAltStack(builder, 0, 1) + // alt stack [creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount, publicKey] + // data statck [marginAsset] + swapAltStack(builder, 0, 2) builder.AddJump(1) builder.SetJumpTarget(0) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] // data statck [ownerSig, newMarginAmount] - swapAltStack(builder, 0, 0) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + swapAltStack(builder, 0, 1) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] // data statck [ownerSig] - cpAltStack(builder, 2) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + cpAltStack(builder, 0) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] // data statck [ownerSig, owner] builder.AddOp(vm.OP_TXSIGHASH) builder.AddOp(vm.OP_SWAP) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] - // data statck [ownerSig, txSigHash, owner] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] + // data statck [ownerSig, txSigHash, publicKey] builder.AddOp(vm.OP_CHECKSIG) builder.AddOp(vm.OP_VERIFY) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] // data statck [] builder.SetJumpTarget(1) builder.AddUint64(0) builder.AddUint64(1) - cpAltStack(builder, 3) + cpAltStack(builder, 4) builder.AddUint64(1) builder.AddOp(vm.OP_PROGRAM) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] // data statck [0, 1, nftAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddUint64(1) - cpAltStack(builder, 0) cpAltStack(builder, 1) + cpAltStack(builder, 2) builder.AddUint64(1) builder.AddOp(vm.OP_PROGRAM) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] // data statck [1, newMarginAmount, newMarginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) return builder.Build() @@ -128,27 +128,26 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { func NewOffer(nftContract []byte) ([]byte, error) { builder := vmutil.NewBuilder() builder.AddJumpIf(0) - builder.AddUint64(1) - builder.AddJump(1) - // need check sig for cancel func - cpAltStack(builder, 2) + cpAltStack(builder, 0) builder.AddOp(vm.OP_TXSIGHASH) builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_CHECKSIG) builder.AddOp(vm.OP_VERIFY) + builder.AddUint64(1) + builder.AddJump(1) builder.SetJumpTarget(0) builder.AddUint64(0) builder.AddUint64(1) - cpAltStack(builder, 3) + cpAltStack(builder, 4) builder.AddUint64(1) builder.AddData(nftContract) builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddUint64(1) - cpAltStack(builder, 0) cpAltStack(builder, 1) + cpAltStack(builder, 2) builder.AddUint64(1) builder.AddData(nftContract) builder.AddOp(vm.OP_CHECKOUTPUT) diff --git a/nft/nft_test.go b/nft/nft_test.go index 554c589e3..61eb13353 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -22,8 +22,9 @@ var ( ETH = testutil.MustDecodeAsset("78de44ffa1bce37b757c9eae8925b5f199dc4621b412ef0f3f46168865284a93") utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") - ownerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("ownerScirpt") - buyerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("buyerScirpt") + ownerScirpt = []byte("ownerScirpt") + buyerScirpt = []byte("buyerScirpt") + publicKey = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") ) // 从2个BTC的押金换成3个BTC的 @@ -40,6 +41,7 @@ func TestEditMargin(t *testing.T) { ownerScirpt, BTC.Bytes(), vm.Uint64Bytes(200000000), + publicKey, } newStateData := [][]byte{ @@ -49,10 +51,11 @@ func TestEditMargin(t *testing.T) { ownerScirpt, BTC.Bytes(), vm.Uint64Bytes(300000000), + publicKey, } arguments := [][]byte{ - testutil.MustDecodeHexString("6c25b3220df660b06bf17ca881e6a31811fc4f33f78e5c0597a1e29b5d0030d9494bff417a237b907eac5cdce1dc0dfe1f258103dee32fcc84a2dd5e8c614209"), + testutil.MustDecodeHexString("b90890b349b0cc0d4e86d21efccc517fdf1bcd0038bbbdf518433905e10ec81130906c816298381a6cedacd037b3084b503c146f7cf710fc759c367da1552a09"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -92,6 +95,7 @@ func TestRegularBuy(t *testing.T) { ownerScirpt, ETH.Bytes(), vm.Uint64Bytes(10000000000), + publicKey, } newStateData := [][]byte{ @@ -101,6 +105,7 @@ func TestRegularBuy(t *testing.T) { buyerScirpt, ETH.Bytes(), vm.Uint64Bytes(15000000000), + publicKey, } arguments := [][]byte{ @@ -148,6 +153,7 @@ func TestBuySwapMargin(t *testing.T) { ownerScirpt, ETH.Bytes(), vm.Uint64Bytes(10000000000), + publicKey, } newStateData := [][]byte{ @@ -157,6 +163,7 @@ func TestBuySwapMargin(t *testing.T) { buyerScirpt, BTC.Bytes(), vm.Uint64Bytes(200000000), + publicKey, } arguments := [][]byte{ @@ -210,6 +217,7 @@ func TestOfferBuy(t *testing.T) { ownerScirpt, ETH.Bytes(), vm.Uint64Bytes(10000000000), + publicKey, } newStateData := [][]byte{ @@ -219,6 +227,7 @@ func TestOfferBuy(t *testing.T) { buyerScirpt, ETH.Bytes(), vm.Uint64Bytes(15000000000), + publicKey, } arguments := [][]byte{ @@ -270,10 +279,11 @@ func TestCancelOffer(t *testing.T) { buyerScirpt, ETH.Bytes(), vm.Uint64Bytes(15000000000), + publicKey, } arguments := [][]byte{ - testutil.MustDecodeHexString("2dbbae17e2aed7639ba212f46fd28b9ccb122c1a24ebd1a48e2dddcaf675252e9adb7c8fe504fa4aad4d054d87701d93d67c5e62bee9ccdc442a39a207dcd106"), + testutil.MustDecodeHexString("5409d2b5395f3516843e60118259be4ef1bea1e77e82b959a82fe5a98ce1a0eccbbbdbbd0156c392e7aacdbfbdec1d827b62813a17535a474c018151b25ca40d"), vm.Uint64Bytes(0), } From 771c1c14b991cebf01ad0402f8e6e2fa0e1f7a50 Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Mon, 25 Oct 2021 11:23:34 +0800 Subject: [PATCH 10/18] Revert "fix pk for sig" This reverts commit d8080df6ccff84ee7087364863f36a89482c2d2b. --- nft/nft.go | 89 +++++++++++++++++++++++++------------------------ nft/nft_test.go | 18 +++------- 2 files changed, 49 insertions(+), 58 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index 332ec9a83..35719d06a 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -6,120 +6,120 @@ import ( ) /* - init alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + init alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] buy data stack [buyer, marginAmount, selecter] edit data stack [newMarginAsset, newMarginAmount, selecter] */ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder := vmutil.NewBuilder() - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [...... selecter] builder.AddJumpIf(0) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount] - cpAltStack(builder, 1) + cpAltStack(builder, 0) builder.AddUint64(marginFold) builder.AddOp(vm.OP_MUL) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, payAmount=marginAmount*marginFold] builder.AddOp(vm.OP_DUP) builder.AddUint64(100) builder.AddOp(vm.OP_DIV) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, payAmount, platformFee] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, payAmount] - cpAltStack(builder, 5) + cpAltStack(builder, 4) builder.AddOp(vm.OP_MUL) builder.AddUint64(10000) builder.AddOp(vm.OP_DIV) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax] builder.AddOp(vm.OP_DUP) builder.AddUint64(2) builder.AddOp(vm.OP_SWAP) - cpAltStack(builder, 2) + cpAltStack(builder, 1) builder.AddUint64(1) - cpAltStack(builder, 6) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + cpAltStack(builder, 5) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount-createrTax] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) builder.AddUint64(3) builder.AddOp(vm.OP_SWAP) - cpAltStack(builder, 2) + cpAltStack(builder, 1) builder.AddUint64(1) builder.AddData(platformScript) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, ownerGot] - cpAltStack(builder, 1) + cpAltStack(builder, 0) builder.AddOp(vm.OP_ADD) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] - // data statck [marginAsset, buyer, newMarginAmount, ownerGot+marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [marginAsset, buyer, newMarginAmount, ownerGot+marginAmount] builder.AddUint64(4) builder.AddOp(vm.OP_SWAP) - cpAltStack(builder, 2) + cpAltStack(builder, 1) builder.AddUint64(1) - cpAltStack(builder, 3) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + cpAltStack(builder, 2) + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount] - swapAltStack(builder, 1, 3) - swapAltStack(builder, 0, 1) - // alt stack [creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount, publicKey] + swapAltStack(builder, 1, 2) + swapAltStack(builder, 0, 0) + // alt stack [creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] // data statck [marginAsset] - swapAltStack(builder, 0, 2) + swapAltStack(builder, 0, 1) builder.AddJump(1) builder.SetJumpTarget(0) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [ownerSig, newMarginAmount] - swapAltStack(builder, 0, 1) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] + swapAltStack(builder, 0, 0) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [ownerSig] - cpAltStack(builder, 0) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] + cpAltStack(builder, 2) + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [ownerSig, owner] builder.AddOp(vm.OP_TXSIGHASH) builder.AddOp(vm.OP_SWAP) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] - // data statck [ownerSig, txSigHash, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [ownerSig, txSigHash, owner] builder.AddOp(vm.OP_CHECKSIG) builder.AddOp(vm.OP_VERIFY) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [] builder.SetJumpTarget(1) builder.AddUint64(0) builder.AddUint64(1) - cpAltStack(builder, 4) + cpAltStack(builder, 3) builder.AddUint64(1) builder.AddOp(vm.OP_PROGRAM) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [0, 1, nftAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddUint64(1) + cpAltStack(builder, 0) cpAltStack(builder, 1) - cpAltStack(builder, 2) builder.AddUint64(1) builder.AddOp(vm.OP_PROGRAM) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount, publicKey] + // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [1, newMarginAmount, newMarginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) return builder.Build() @@ -128,26 +128,27 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { func NewOffer(nftContract []byte) ([]byte, error) { builder := vmutil.NewBuilder() builder.AddJumpIf(0) + builder.AddUint64(1) + builder.AddJump(1) + // need check sig for cancel func - cpAltStack(builder, 0) + cpAltStack(builder, 2) builder.AddOp(vm.OP_TXSIGHASH) builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_CHECKSIG) builder.AddOp(vm.OP_VERIFY) - builder.AddUint64(1) - builder.AddJump(1) builder.SetJumpTarget(0) builder.AddUint64(0) builder.AddUint64(1) - cpAltStack(builder, 4) + cpAltStack(builder, 3) builder.AddUint64(1) builder.AddData(nftContract) builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddUint64(1) + cpAltStack(builder, 0) cpAltStack(builder, 1) - cpAltStack(builder, 2) builder.AddUint64(1) builder.AddData(nftContract) builder.AddOp(vm.OP_CHECKOUTPUT) diff --git a/nft/nft_test.go b/nft/nft_test.go index 61eb13353..554c589e3 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -22,9 +22,8 @@ var ( ETH = testutil.MustDecodeAsset("78de44ffa1bce37b757c9eae8925b5f199dc4621b412ef0f3f46168865284a93") utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") - ownerScirpt = []byte("ownerScirpt") - buyerScirpt = []byte("buyerScirpt") - publicKey = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") + ownerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("ownerScirpt") + buyerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("buyerScirpt") ) // 从2个BTC的押金换成3个BTC的 @@ -41,7 +40,6 @@ func TestEditMargin(t *testing.T) { ownerScirpt, BTC.Bytes(), vm.Uint64Bytes(200000000), - publicKey, } newStateData := [][]byte{ @@ -51,11 +49,10 @@ func TestEditMargin(t *testing.T) { ownerScirpt, BTC.Bytes(), vm.Uint64Bytes(300000000), - publicKey, } arguments := [][]byte{ - testutil.MustDecodeHexString("b90890b349b0cc0d4e86d21efccc517fdf1bcd0038bbbdf518433905e10ec81130906c816298381a6cedacd037b3084b503c146f7cf710fc759c367da1552a09"), + testutil.MustDecodeHexString("6c25b3220df660b06bf17ca881e6a31811fc4f33f78e5c0597a1e29b5d0030d9494bff417a237b907eac5cdce1dc0dfe1f258103dee32fcc84a2dd5e8c614209"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -95,7 +92,6 @@ func TestRegularBuy(t *testing.T) { ownerScirpt, ETH.Bytes(), vm.Uint64Bytes(10000000000), - publicKey, } newStateData := [][]byte{ @@ -105,7 +101,6 @@ func TestRegularBuy(t *testing.T) { buyerScirpt, ETH.Bytes(), vm.Uint64Bytes(15000000000), - publicKey, } arguments := [][]byte{ @@ -153,7 +148,6 @@ func TestBuySwapMargin(t *testing.T) { ownerScirpt, ETH.Bytes(), vm.Uint64Bytes(10000000000), - publicKey, } newStateData := [][]byte{ @@ -163,7 +157,6 @@ func TestBuySwapMargin(t *testing.T) { buyerScirpt, BTC.Bytes(), vm.Uint64Bytes(200000000), - publicKey, } arguments := [][]byte{ @@ -217,7 +210,6 @@ func TestOfferBuy(t *testing.T) { ownerScirpt, ETH.Bytes(), vm.Uint64Bytes(10000000000), - publicKey, } newStateData := [][]byte{ @@ -227,7 +219,6 @@ func TestOfferBuy(t *testing.T) { buyerScirpt, ETH.Bytes(), vm.Uint64Bytes(15000000000), - publicKey, } arguments := [][]byte{ @@ -279,11 +270,10 @@ func TestCancelOffer(t *testing.T) { buyerScirpt, ETH.Bytes(), vm.Uint64Bytes(15000000000), - publicKey, } arguments := [][]byte{ - testutil.MustDecodeHexString("5409d2b5395f3516843e60118259be4ef1bea1e77e82b959a82fe5a98ce1a0eccbbbdbbd0156c392e7aacdbfbdec1d827b62813a17535a474c018151b25ca40d"), + testutil.MustDecodeHexString("2dbbae17e2aed7639ba212f46fd28b9ccb122c1a24ebd1a48e2dddcaf675252e9adb7c8fe504fa4aad4d054d87701d93d67c5e62bee9ccdc442a39a207dcd106"), vm.Uint64Bytes(0), } From d1e3336763ca2b8e9f67a12c129a26f30968fa83 Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Mon, 25 Oct 2021 11:23:41 +0800 Subject: [PATCH 11/18] Revert "add sig for nft contract func" This reverts commit c3610f1fb05bff099b1ae6773f5d247326d724d0. --- nft/nft.go | 22 +--------------------- nft/nft_test.go | 6 ++---- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index 35719d06a..bed1d2780 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -89,20 +89,9 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.SetJumpTarget(0) // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [ownerSig, newMarginAmount] + // data statck [newMarginAmount] swapAltStack(builder, 0, 0) // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] - // data statck [ownerSig] - cpAltStack(builder, 2) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] - // data statck [ownerSig, owner] - builder.AddOp(vm.OP_TXSIGHASH) - builder.AddOp(vm.OP_SWAP) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] - // data statck [ownerSig, txSigHash, owner] - builder.AddOp(vm.OP_CHECKSIG) - builder.AddOp(vm.OP_VERIFY) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [] builder.SetJumpTarget(1) builder.AddUint64(0) @@ -130,14 +119,6 @@ func NewOffer(nftContract []byte) ([]byte, error) { builder.AddJumpIf(0) builder.AddUint64(1) builder.AddJump(1) - - // need check sig for cancel func - cpAltStack(builder, 2) - builder.AddOp(vm.OP_TXSIGHASH) - builder.AddOp(vm.OP_SWAP) - builder.AddOp(vm.OP_CHECKSIG) - builder.AddOp(vm.OP_VERIFY) - builder.SetJumpTarget(0) builder.AddUint64(0) builder.AddUint64(1) @@ -153,7 +134,6 @@ func NewOffer(nftContract []byte) ([]byte, error) { builder.AddData(nftContract) builder.AddOp(vm.OP_CHECKOUTPUT) builder.SetJumpTarget(1) - return builder.Build() } diff --git a/nft/nft_test.go b/nft/nft_test.go index 554c589e3..0f27f1a7a 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -22,8 +22,8 @@ var ( ETH = testutil.MustDecodeAsset("78de44ffa1bce37b757c9eae8925b5f199dc4621b412ef0f3f46168865284a93") utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") - ownerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("ownerScirpt") - buyerScirpt = testutil.MustDecodeHexString("0100000000000000000000000000000000000000000000000000000000000000") //[]byte("buyerScirpt") + ownerScirpt = []byte("ownerScirpt") + buyerScirpt = []byte("buyerScirpt") ) // 从2个BTC的押金换成3个BTC的 @@ -52,7 +52,6 @@ func TestEditMargin(t *testing.T) { } arguments := [][]byte{ - testutil.MustDecodeHexString("6c25b3220df660b06bf17ca881e6a31811fc4f33f78e5c0597a1e29b5d0030d9494bff417a237b907eac5cdce1dc0dfe1f258103dee32fcc84a2dd5e8c614209"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -273,7 +272,6 @@ func TestCancelOffer(t *testing.T) { } arguments := [][]byte{ - testutil.MustDecodeHexString("2dbbae17e2aed7639ba212f46fd28b9ccb122c1a24ebd1a48e2dddcaf675252e9adb7c8fe504fa4aad4d054d87701d93d67c5e62bee9ccdc442a39a207dcd106"), vm.Uint64Bytes(0), } From 952eaabc18ddec131f77dd6670122f9f7cf83ee6 Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Mon, 25 Oct 2021 11:28:48 +0800 Subject: [PATCH 12/18] pk to stack bottom and fix case --- nft/nft.go | 61 +++++++++++++++++++++++++++++++------------------ nft/nft_test.go | 24 ++++++++++++++++--- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index bed1d2780..5cbc349cf 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -6,37 +6,37 @@ import ( ) /* - init alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + init alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] buy data stack [buyer, marginAmount, selecter] - edit data stack [newMarginAsset, newMarginAmount, selecter] + edit data stack [signature, newMarginAsset, newMarginAmount, selecter] */ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder := vmutil.NewBuilder() - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [...... selecter] builder.AddJumpIf(0) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount] cpAltStack(builder, 0) builder.AddUint64(marginFold) builder.AddOp(vm.OP_MUL) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, payAmount=marginAmount*marginFold] builder.AddOp(vm.OP_DUP) builder.AddUint64(100) builder.AddOp(vm.OP_DIV) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, payAmount, platformFee] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, payAmount] cpAltStack(builder, 4) builder.AddOp(vm.OP_MUL) builder.AddUint64(10000) builder.AddOp(vm.OP_DIV) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax] builder.AddOp(vm.OP_DUP) builder.AddUint64(2) @@ -44,12 +44,12 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { cpAltStack(builder, 1) builder.AddUint64(1) cpAltStack(builder, 5) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount-createrTax] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) @@ -58,48 +58,58 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { cpAltStack(builder, 1) builder.AddUint64(1) builder.AddData(platformScript) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, ownerGot] cpAltStack(builder, 0) builder.AddOp(vm.OP_ADD) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, ownerGot+marginAmount] builder.AddUint64(4) builder.AddOp(vm.OP_SWAP) cpAltStack(builder, 1) builder.AddUint64(1) cpAltStack(builder, 2) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount] swapAltStack(builder, 1, 2) swapAltStack(builder, 0, 0) - // alt stack [creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] // data statck [marginAsset] swapAltStack(builder, 0, 1) builder.AddJump(1) builder.SetJumpTarget(0) - // alt stack [creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [newMarginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [ownerSignature, newMarginAmount] swapAltStack(builder, 0, 0) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] - // data statck [] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [ownerSignature] + cpAltStack(builder, 6) + // alt stack [publicKey, creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [ownerSignature, publicKey] + builder.AddOp(vm.OP_TXSIGHASH) + builder.AddOp(vm.OP_SWAP) + // alt stack [publicKey, creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // data statck [ownerSignature, txSigHash, publicKey] + builder.AddOp(vm.OP_CHECKSIG) + builder.AddOp(vm.OP_VERIFY) + builder.SetJumpTarget(1) builder.AddUint64(0) builder.AddUint64(1) cpAltStack(builder, 3) builder.AddUint64(1) builder.AddOp(vm.OP_PROGRAM) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [0, 1, nftAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) @@ -108,7 +118,7 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { cpAltStack(builder, 1) builder.AddUint64(1) builder.AddOp(vm.OP_PROGRAM) - // alt stack [creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] + // alt stack [publicKey, creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [1, newMarginAmount, newMarginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) return builder.Build() @@ -117,6 +127,13 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { func NewOffer(nftContract []byte) ([]byte, error) { builder := vmutil.NewBuilder() builder.AddJumpIf(0) + // need check sig for cancel func + cpAltStack(builder, 6) + builder.AddOp(vm.OP_TXSIGHASH) + builder.AddOp(vm.OP_SWAP) + builder.AddOp(vm.OP_CHECKSIG) + builder.AddOp(vm.OP_VERIFY) + builder.AddUint64(1) builder.AddJump(1) builder.SetJumpTarget(0) diff --git a/nft/nft_test.go b/nft/nft_test.go index 0f27f1a7a..2f34f6ea3 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -24,6 +24,7 @@ var ( utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") ownerScirpt = []byte("ownerScirpt") buyerScirpt = []byte("buyerScirpt") + publicKey = testutil.MustDecodeHexString("7642ba797fd89d1f98a8559b4ca74123697dd4dee882955acd0da9010a80d64e") ) // 从2个BTC的押金换成3个BTC的 @@ -34,6 +35,7 @@ func TestEditMargin(t *testing.T) { } oldStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -43,6 +45,7 @@ func TestEditMargin(t *testing.T) { } newStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -51,7 +54,14 @@ func TestEditMargin(t *testing.T) { vm.Uint64Bytes(300000000), } - arguments := [][]byte{ + arguments1 := [][]byte{ + testutil.MustDecodeHexString("74202524d9fdf913c2b176f9c81c3f7d433440d944f12a87f9d78f3294b30e1d8a388716887ca20c012064059054e1c036e15d2da65441ff93bcb4593e374e09"), + vm.Uint64Bytes(300000000), + vm.Uint64Bytes(1), + } + + arguments2 := [][]byte{ + testutil.MustDecodeHexString("bcdda03bd6b1f5605c51e58cb1230c76fdc06b837118741a586275c6653979cd632f796741d79c652a06c23f73a0e2f7d9086ea39b4e9d9793e8835b5e013d07"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -60,8 +70,8 @@ func TestEditMargin(t *testing.T) { Version: 1, SerializedSize: 10000, Inputs: []*types.TxInput{ - types.NewSpendInput(arguments, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), - types.NewSpendInput(arguments, utxoSourceID, BTC, 200000000, 1, contract, oldStateData), + types.NewSpendInput(arguments1, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), + types.NewSpendInput(arguments2, utxoSourceID, BTC, 200000000, 1, contract, oldStateData), types.NewSpendInput(nil, utxoSourceID, BTC, 100000000, 2, anyCanSpendScript, nil), types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), }, @@ -85,6 +95,7 @@ func TestRegularBuy(t *testing.T) { } oldStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -94,6 +105,7 @@ func TestRegularBuy(t *testing.T) { } newStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -141,6 +153,7 @@ func TestBuySwapMargin(t *testing.T) { } oldStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -150,6 +163,7 @@ func TestBuySwapMargin(t *testing.T) { } newStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -203,6 +217,7 @@ func TestOfferBuy(t *testing.T) { } oldStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -212,6 +227,7 @@ func TestOfferBuy(t *testing.T) { } newStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -263,6 +279,7 @@ func TestCancelOffer(t *testing.T) { } newStateData := [][]byte{ + publicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -272,6 +289,7 @@ func TestCancelOffer(t *testing.T) { } arguments := [][]byte{ + testutil.MustDecodeHexString("413c6f447ce86ef2061eb9b481586a78a07604398d39866d206a1595901159170267e65baf7261bcf62244c21bd407490d617511a321bdd25e70ca799c07dd04"), vm.Uint64Bytes(0), } From 8cb450e077ccb3a8edc906da6380161d188adef6 Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Mon, 25 Oct 2021 21:04:39 +0800 Subject: [PATCH 13/18] modify cancel case --- nft/nft_test.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nft/nft_test.go b/nft/nft_test.go index 2f34f6ea3..518a647eb 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -288,8 +288,13 @@ func TestCancelOffer(t *testing.T) { vm.Uint64Bytes(15000000000), } - arguments := [][]byte{ - testutil.MustDecodeHexString("413c6f447ce86ef2061eb9b481586a78a07604398d39866d206a1595901159170267e65baf7261bcf62244c21bd407490d617511a321bdd25e70ca799c07dd04"), + arguments1 := [][]byte{ + testutil.MustDecodeHexString("dda495953ff63af7775bfd8ad1b8b54900849a202668d35454beb6d33ae18057abbfc2a8f5691876083a364f713f54ea4b71cb9d0436d7b1c9ef194ee42e2304"), + vm.Uint64Bytes(0), + } + + arguments2 := [][]byte{ + testutil.MustDecodeHexString("2efd75e44777be73300210569bb4002e8942064718092a958658150f54f6a002806123a20960bbb5ce4d85cbff7827ca994344d360119041d266e3a56ddde904"), vm.Uint64Bytes(0), } @@ -297,11 +302,13 @@ func TestCancelOffer(t *testing.T) { Version: 1, SerializedSize: 10000, Inputs: []*types.TxInput{ - types.NewSpendInput(arguments, utxoSourceID, ETH, 135000000000, 2, offer, newStateData), + types.NewSpendInput(arguments1, utxoSourceID, ETH, 135000000000, 2, offer, newStateData), + types.NewSpendInput(arguments2, utxoSourceID, BTC, 135000000000, 1, offer, newStateData), types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), }, Outputs: []*types.TxOutput{ types.NewOriginalTxOutput(ETH, 135000000000, ownerScirpt, newStateData), + types.NewOriginalTxOutput(BTC, 135000000000, ownerScirpt, newStateData), }, }) From 05a552dc2adb792f68744ae088450848a16a4a7a Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Tue, 26 Oct 2021 17:38:03 +0800 Subject: [PATCH 14/18] add sub margin --- nft/nft.go | 26 +++++++++++++++++-- nft/nft_test.go | 69 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index 5cbc349cf..0b0e6b053 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -7,7 +7,7 @@ import ( /* init alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - buy data stack [buyer, marginAmount, selecter] + buy data stack [marginAsset, buyer, newMarginAmount, selecter] edit data stack [signature, newMarginAsset, newMarginAmount, selecter] */ @@ -15,6 +15,11 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder := vmutil.NewBuilder() // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [...... selecter] + builder.AddOp(vm.OP_DUP) + builder.AddUint64(2) + builder.AddOp(vm.OP_EQUAL) + builder.AddJumpIf(2) + builder.AddJumpIf(0) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [marginAsset, buyer, newMarginAmount] @@ -45,7 +50,7 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.AddUint64(1) cpAltStack(builder, 5) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, PROGRAM] + // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, creater] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) @@ -87,6 +92,23 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { swapAltStack(builder, 0, 1) builder.AddJump(1) + builder.SetJumpTarget(2) + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [ownerSignature, newMarginAmount] + builder.AddOp(vm.OP_DUP) + cpAltStack(builder, 0) + builder.AddOp(vm.OP_DUP) + builder.AddOp(vm.OP_SUB) + builder.AddUint64(2) + builder.AddOp(vm.OP_SWAP) + cpAltStack(builder, 1) + builder.AddUint64(1) + cpAltStack(builder, 2) + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data statck [ownerSignature, newMarginAmount, 2, marginAmount-newMarginAmount, marginAsset, 1, owner] + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + builder.SetJumpTarget(0) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [ownerSignature, newMarginAmount] diff --git a/nft/nft_test.go b/nft/nft_test.go index 518a647eb..67f88d8ae 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -28,7 +28,7 @@ var ( ) // 从2个BTC的押金换成3个BTC的 -func TestEditMargin(t *testing.T) { +func TestAddMargin(t *testing.T) { contract, err := NewContract(platformScript, marginFold) if err != nil { t.Fatal(err) @@ -55,13 +55,13 @@ func TestEditMargin(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("74202524d9fdf913c2b176f9c81c3f7d433440d944f12a87f9d78f3294b30e1d8a388716887ca20c012064059054e1c036e15d2da65441ff93bcb4593e374e09"), + testutil.MustDecodeHexString("a56a34053c2d0aeea5d590df4aa7f0694da5faf7f5e4d8848087de6de1d273fcefd5c04ed9ec4d95e40747bc8d145c12d01a6b09a3284c27b66d714d0a3fc203"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("bcdda03bd6b1f5605c51e58cb1230c76fdc06b837118741a586275c6653979cd632f796741d79c652a06c23f73a0e2f7d9086ea39b4e9d9793e8835b5e013d07"), + testutil.MustDecodeHexString("5a4c7a9dd7eec3e230b4f09f44f786d5864374c8208cb88cf00139c6f3bd65596c573bd486f98f7934dac24a8c35da028cc90a6a8df4a5c982f0e9a225fbc603"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -87,6 +87,65 @@ func TestEditMargin(t *testing.T) { } } +func TestSubMargin(t *testing.T) { + contract, err := NewContract(platformScript, marginFold) + if err != nil { + t.Fatal(err) + } + + oldStateData := [][]byte{ + publicKey, + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + BTC.Bytes(), + vm.Uint64Bytes(300000000), + } + + newStateData := [][]byte{ + publicKey, + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + BTC.Bytes(), + vm.Uint64Bytes(200000000), + } + + arguments1 := [][]byte{ + testutil.MustDecodeHexString("02b8224c5aa208101fee786a13a1db435255107eca68ff9ca436f668fc85e984351be3bef911fab3fa30f65db1f7c87c98a8bfa1392709dc5fae65316e4f4e05"), + vm.Uint64Bytes(200000000), + vm.Uint64Bytes(1), + } + + arguments2 := [][]byte{ + testutil.MustDecodeHexString("475a68712f1d5eac547221921f7e6ff4d2d1414ef0c9a0483f6eb0dac604fd330f34029886a3fba1f5e9dabcedc5ee0c062187a365cd9b81099f462a1aa02c06"), + vm.Uint64Bytes(200000000), + vm.Uint64Bytes(1), + } + + tx := types.NewTx(types.TxData{ + Version: 1, + SerializedSize: 10000, + Inputs: []*types.TxInput{ + types.NewSpendInput(arguments1, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), + types.NewSpendInput(arguments2, utxoSourceID, BTC, 300000000, 1, contract, oldStateData), + types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), + }, + Outputs: []*types.TxOutput{ + types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), + types.NewOriginalTxOutput(BTC, 200000000, contract, newStateData), + types.NewOriginalTxOutput(BTC, 100000000, ownerScirpt, oldStateData), + }, + }) + + _, err = validation.ValidateTx(tx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{}}, func(prog []byte) ([]byte, error) { return nil, nil }) + if err != nil { + t.Fatal(err) + } +} + // 10个ETH质押被买走, 然后被质押15个ETH func TestRegularBuy(t *testing.T) { contract, err := NewContract(platformScript, marginFold) @@ -289,12 +348,12 @@ func TestCancelOffer(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("dda495953ff63af7775bfd8ad1b8b54900849a202668d35454beb6d33ae18057abbfc2a8f5691876083a364f713f54ea4b71cb9d0436d7b1c9ef194ee42e2304"), + testutil.MustDecodeHexString("471cf24e018b549d5740cc2dca0d34ed33f5706c3d660ec8bbc21393731d0da51814b305009f5300a0a863a0c4c7ca3d8cc5d38cc5e0ec11e7eeec5161496d02"), vm.Uint64Bytes(0), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("2efd75e44777be73300210569bb4002e8942064718092a958658150f54f6a002806123a20960bbb5ce4d85cbff7827ca994344d360119041d266e3a56ddde904"), + testutil.MustDecodeHexString("3318b9ea0e808db8925f60ffba42c68106263fa2189d7dde68ef1c6d0c0d0d5efd24aa7b0d3e960e81880dd35828341a17585c41ad4bd9de569c765aba39ca02"), vm.Uint64Bytes(0), } From 6a24b8256a31132a2e9862e0a9071306827799cb Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Wed, 27 Oct 2021 14:04:46 +0800 Subject: [PATCH 15/18] fix buyer pk --- nft/nft.go | 31 +++++++++++++++++-------------- nft/nft_test.go | 46 +++++++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index 0b0e6b053..d1d492b00 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -7,7 +7,7 @@ import ( /* init alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - buy data stack [marginAsset, buyer, newMarginAmount, selecter] + buy data stack [newPublicKey, marginAsset, buyer, newMarginAmount, selecter] edit data stack [signature, newMarginAsset, newMarginAmount, selecter] */ @@ -22,27 +22,27 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.AddJumpIf(0) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount] cpAltStack(builder, 0) builder.AddUint64(marginFold) builder.AddOp(vm.OP_MUL) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, payAmount=marginAmount*marginFold] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, payAmount=marginAmount*marginFold] builder.AddOp(vm.OP_DUP) builder.AddUint64(100) builder.AddOp(vm.OP_DIV) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, payAmount, platformFee] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, payAmount, platformFee] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, payAmount] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, platformFee, payAmount, payAmount] cpAltStack(builder, 4) builder.AddOp(vm.OP_MUL) builder.AddUint64(10000) builder.AddOp(vm.OP_DIV) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax] builder.AddOp(vm.OP_DUP) builder.AddUint64(2) builder.AddOp(vm.OP_SWAP) @@ -50,12 +50,12 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.AddUint64(1) cpAltStack(builder, 5) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, creater] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, platformFee, payAmount, createrTax, 2, createrTax, marginAsset, 1, creater] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, platformFee, payAmount-createrTax] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, platformFee, payAmount-createrTax] builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_DUP) builder.AddUint64(3) @@ -64,32 +64,35 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.AddUint64(1) builder.AddData(platformScript) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, payAmount-createrTax, platformFee, 3, platformFee, marginAsset, 1, platformScript] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) builder.AddOp(vm.OP_SUB) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, ownerGot] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, ownerGot] cpAltStack(builder, 0) builder.AddOp(vm.OP_ADD) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, ownerGot+marginAmount] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, ownerGot+marginAmount] builder.AddUint64(4) builder.AddOp(vm.OP_SWAP) cpAltStack(builder, 1) builder.AddUint64(1) cpAltStack(builder, 2) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount, 4, ownerGot+marginAmount, marginAsset, 1, owner] builder.AddOp(vm.OP_CHECKOUTPUT) builder.AddOp(vm.OP_VERIFY) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data statck [marginAsset, buyer, newMarginAmount] + // data statck [newPublicKey, marginAsset, buyer, newMarginAmount] swapAltStack(builder, 1, 2) swapAltStack(builder, 0, 0) // alt stack [publicKey, creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] - // data statck [marginAsset] + // data statck [newPublicKey, marginAsset] swapAltStack(builder, 0, 1) + swapAltStack(builder, 0, 6) + // alt stack [newPublicKey, creater, taxRate, nftAsset, buyer, marginAsset, newMarginAmount] + // data statck [] builder.AddJump(1) builder.SetJumpTarget(2) diff --git a/nft/nft_test.go b/nft/nft_test.go index 67f88d8ae..f8a1cd557 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -21,10 +21,11 @@ var ( BTC = testutil.MustDecodeAsset("bda946b3110fa46fd94346ce3f05f0760f1b9de72e238835bc4d19f9d64f1742") ETH = testutil.MustDecodeAsset("78de44ffa1bce37b757c9eae8925b5f199dc4621b412ef0f3f46168865284a93") - utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") - ownerScirpt = []byte("ownerScirpt") - buyerScirpt = []byte("buyerScirpt") - publicKey = testutil.MustDecodeHexString("7642ba797fd89d1f98a8559b4ca74123697dd4dee882955acd0da9010a80d64e") + utxoSourceID = testutil.MustDecodeHash("762ec536ea64f71feac5fd4000a4807fc8e9d08d757889bd0206a02b79f9db8e") + ownerScirpt = []byte("ownerScirpt") + buyerScirpt = []byte("buyerScirpt") + ownerPublicKey = testutil.MustDecodeHexString("7642ba797fd89d1f98a8559b4ca74123697dd4dee882955acd0da9010a80d64e") + buyerPublicKey = testutil.MustDecodeHexString("a0a5b2a1148cc8eb4fbdb739574164ecd6be15f4da31b54b846de5c5c83815b3") ) // 从2个BTC的押金换成3个BTC的 @@ -35,7 +36,7 @@ func TestAddMargin(t *testing.T) { } oldStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -45,7 +46,7 @@ func TestAddMargin(t *testing.T) { } newStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -55,13 +56,13 @@ func TestAddMargin(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("a56a34053c2d0aeea5d590df4aa7f0694da5faf7f5e4d8848087de6de1d273fcefd5c04ed9ec4d95e40747bc8d145c12d01a6b09a3284c27b66d714d0a3fc203"), + testutil.MustDecodeHexString("d51a48a7b5918de3cbf97de1a047af34fcb144c0308558a6ed5c4a12f4f338b9ccef23cd51937116412059569ba966cdc3c19fd58caa8aca4c2b9323e15cc90d"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("5a4c7a9dd7eec3e230b4f09f44f786d5864374c8208cb88cf00139c6f3bd65596c573bd486f98f7934dac24a8c35da028cc90a6a8df4a5c982f0e9a225fbc603"), + testutil.MustDecodeHexString("62fb14d988c57692a8860c25915e2fc7dbf4143388ede4200e79cc6dbf8751274cc0192d914137b9bb9f36b89d5e5f5909d041699f3d5fc1b27348e106a1520e"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -94,7 +95,7 @@ func TestSubMargin(t *testing.T) { } oldStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -104,7 +105,7 @@ func TestSubMargin(t *testing.T) { } newStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -114,13 +115,13 @@ func TestSubMargin(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("02b8224c5aa208101fee786a13a1db435255107eca68ff9ca436f668fc85e984351be3bef911fab3fa30f65db1f7c87c98a8bfa1392709dc5fae65316e4f4e05"), + testutil.MustDecodeHexString("ba9772c480c349dc237f15e9606963224d7d1211072a79b4c34a045d19bb95a2bc20fba10f70097775a5b4e2a5c9f016ca96713fa19bdc5dfc0b4d21a9c3d407"), vm.Uint64Bytes(200000000), vm.Uint64Bytes(1), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("475a68712f1d5eac547221921f7e6ff4d2d1414ef0c9a0483f6eb0dac604fd330f34029886a3fba1f5e9dabcedc5ee0c062187a365cd9b81099f462a1aa02c06"), + testutil.MustDecodeHexString("d7d82e40d5a6022aa2b7eb602ded566fa748e9549bd73146d7c2251401805f113ed2f5d76a5208ebfae989e5c7da37e976d59564bf05f9682b5057e163121407"), vm.Uint64Bytes(200000000), vm.Uint64Bytes(1), } @@ -154,7 +155,7 @@ func TestRegularBuy(t *testing.T) { } oldStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -164,7 +165,7 @@ func TestRegularBuy(t *testing.T) { } newStateData := [][]byte{ - publicKey, + buyerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -174,6 +175,7 @@ func TestRegularBuy(t *testing.T) { } arguments := [][]byte{ + buyerPublicKey, ETH.Bytes(), buyerScirpt, vm.Uint64Bytes(15000000000), @@ -212,7 +214,7 @@ func TestBuySwapMargin(t *testing.T) { } oldStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -222,7 +224,7 @@ func TestBuySwapMargin(t *testing.T) { } newStateData := [][]byte{ - publicKey, + buyerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -232,6 +234,7 @@ func TestBuySwapMargin(t *testing.T) { } arguments := [][]byte{ + buyerPublicKey, BTC.Bytes(), buyerScirpt, vm.Uint64Bytes(200000000), @@ -276,7 +279,7 @@ func TestOfferBuy(t *testing.T) { } oldStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -286,7 +289,7 @@ func TestOfferBuy(t *testing.T) { } newStateData := [][]byte{ - publicKey, + buyerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -296,6 +299,7 @@ func TestOfferBuy(t *testing.T) { } arguments := [][]byte{ + buyerPublicKey, ETH.Bytes(), buyerScirpt, vm.Uint64Bytes(15000000000), @@ -338,7 +342,7 @@ func TestCancelOffer(t *testing.T) { } newStateData := [][]byte{ - publicKey, + ownerPublicKey, createrScript, vm.Uint64Bytes(taxRate), nftAsset.Bytes(), @@ -348,12 +352,12 @@ func TestCancelOffer(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("471cf24e018b549d5740cc2dca0d34ed33f5706c3d660ec8bbc21393731d0da51814b305009f5300a0a863a0c4c7ca3d8cc5d38cc5e0ec11e7eeec5161496d02"), + testutil.MustDecodeHexString("4afb322c65d4d966b20de6a9fb891a926bb04fb9dcdcced8bf58b0caffbc0ed7798d6874f25bc34cec2ffe5a017fa10701d8c81812d174a10bd3e7a1fc5cb300"), vm.Uint64Bytes(0), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("3318b9ea0e808db8925f60ffba42c68106263fa2189d7dde68ef1c6d0c0d0d5efd24aa7b0d3e960e81880dd35828341a17585c41ad4bd9de569c765aba39ca02"), + testutil.MustDecodeHexString("4f7b9b4f15dfba12e80789619d33491a7537a68667f75b6889d40aa7138c9c497d3aaff3f7a7830cf155562ecd2d500bbcd453d323bcb0926d0e91ea09f42507"), vm.Uint64Bytes(0), } From 407fde06954013a02a6e1a079e0638d1cc1ded2e Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Mon, 15 Nov 2021 18:36:53 +0800 Subject: [PATCH 16/18] add transfer --- nft/nft.go | 37 +++++++++++++++++++++++++++++++ nft/nft_test.go | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/nft/nft.go b/nft/nft.go index d1d492b00..cb9ef1aef 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -179,6 +179,43 @@ func NewOffer(nftContract []byte) ([]byte, error) { return builder.Build() } +/* + init alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + init data stack [signature, buyerPublicKey, buyerScirpt] +*/ +func NewTransfer() ([]byte, error) { + builder := vmutil.NewBuilder() + + builder.AddUint64(2) + builder.AddOp(vm.OP_ROLL) + cpAltStack(builder, 6) + builder.AddOp(vm.OP_TXSIGHASH) + builder.AddOp(vm.OP_SWAP) + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data stack [buyerPublicKey, buyerScirpt, ownerSignature, txSigHash, publicKey] + builder.AddOp(vm.OP_CHECKSIG) + builder.AddOp(vm.OP_VERIFY) + + swapAltStack(builder, 0, 2) + swapAltStack(builder, 0, 6) + + builder.AddUint64(0) + builder.AddUint64(1) + cpAltStack(builder, 3) + builder.AddUint64(1) + builder.AddOp(vm.OP_PROGRAM) + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + + builder.AddUint64(1) + cpAltStack(builder, 0) + cpAltStack(builder, 1) + builder.AddUint64(1) + builder.AddOp(vm.OP_PROGRAM) + builder.AddOp(vm.OP_CHECKOUTPUT) + return builder.Build() +} + func swapAltStack(builder *vmutil.Builder, dataPos, AltPos uint64) { for i := uint64(0); i <= AltPos; i++ { builder.AddOp(vm.OP_FROMALTSTACK) diff --git a/nft/nft_test.go b/nft/nft_test.go index f8a1cd557..e82289495 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -147,6 +147,64 @@ func TestSubMargin(t *testing.T) { } } +func TestTransferNft(t *testing.T) { + contract, err := NewTransfer() + if err != nil { + t.Fatal(err) + } + + oldStateData := [][]byte{ + ownerPublicKey, + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + ownerScirpt, + BTC.Bytes(), + vm.Uint64Bytes(300000000), + } + + newStateData := [][]byte{ + buyerPublicKey, + createrScript, + vm.Uint64Bytes(taxRate), + nftAsset.Bytes(), + buyerScirpt, + BTC.Bytes(), + vm.Uint64Bytes(300000000), + } + + arguments1 := [][]byte{ + testutil.MustDecodeHexString("2f78dd3131fec66074654ab6f5c8d18bd9e07937b176c55b74b019d1a1956446cbbfc7fd1d13411f17e3e7e81a83301129bb9e355514a2487dee5635e4b86504"), + buyerPublicKey, + buyerScirpt, + } + + arguments2 := [][]byte{ + testutil.MustDecodeHexString("b64f6a98f6bc5b35ed8f88fab7faa3700a25e574fbbe696b438fdcc486a15eb4bdad05c4509c2835bd0ca1e8dd615fcb4ca79599e68f2adde1211ae014750f0f"), + buyerPublicKey, + buyerScirpt, + } + + tx := types.NewTx(types.TxData{ + Version: 1, + SerializedSize: 10000, + Inputs: []*types.TxInput{ + types.NewSpendInput(arguments1, utxoSourceID, nftAsset, 1, 0, contract, oldStateData), + types.NewSpendInput(arguments2, utxoSourceID, BTC, 300000000, 1, contract, oldStateData), + types.NewSpendInput(nil, utxoSourceID, *consensus.BTMAssetID, 100000000, 1, anyCanSpendScript, nil), + }, + Outputs: []*types.TxOutput{ + types.NewOriginalTxOutput(nftAsset, 1, contract, newStateData), + types.NewOriginalTxOutput(BTC, 300000000, contract, newStateData), + }, + }) + + _, err = validation.ValidateTx(tx.Tx, &bc.Block{BlockHeader: &bc.BlockHeader{}}, func(prog []byte) ([]byte, error) { return nil, nil }) + if err != nil { + t.Fatal(err) + } +} + // 10个ETH质押被买走, 然后被质押15个ETH func TestRegularBuy(t *testing.T) { contract, err := NewContract(platformScript, marginFold) From ebccdc84537cb1f92dc9e01ac0c6b47296b0d401 Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Tue, 16 Nov 2021 14:15:39 +0800 Subject: [PATCH 17/18] adjust transfer & fix submagrin check --- nft/nft.go | 84 +++++++++++++++++++++++++++---------------------- nft/nft_test.go | 24 +++++++------- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index cb9ef1aef..bf7c57833 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -13,8 +13,51 @@ import ( func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder := vmutil.NewBuilder() + /* + For transfer nft: + init alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + init data stack [signature, buyerPublicKey, buyerScirpt, selecter] + */ + builder.AddOp(vm.OP_DUP) + builder.AddUint64(3) + builder.AddOp(vm.OP_EQUAL) + builder.AddJumpIf(3) + builder.AddJump(4) + + builder.SetJumpTarget(3) + builder.AddOp(vm.OP_DROP) + + builder.AddUint64(2) + builder.AddOp(vm.OP_ROLL) + cpAltStack(builder, 6) + builder.AddOp(vm.OP_TXSIGHASH) + builder.AddOp(vm.OP_SWAP) + // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] + // data stack [buyerPublicKey, buyerScirpt, ownerSignature, txSigHash, publicKey] + builder.AddOp(vm.OP_CHECKSIG) + builder.AddOp(vm.OP_VERIFY) + + swapAltStack(builder, 0, 2) + swapAltStack(builder, 0, 6) + + builder.AddUint64(0) + builder.AddUint64(1) + cpAltStack(builder, 3) + builder.AddUint64(1) + builder.AddOp(vm.OP_PROGRAM) + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddOp(vm.OP_VERIFY) + + builder.AddUint64(1) + cpAltStack(builder, 0) + cpAltStack(builder, 1) + builder.AddUint64(1) + builder.AddOp(vm.OP_PROGRAM) + builder.AddOp(vm.OP_CHECKOUTPUT) + builder.AddJump(5) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [...... selecter] + builder.SetJumpTarget(4) builder.AddOp(vm.OP_DUP) builder.AddUint64(2) builder.AddOp(vm.OP_EQUAL) @@ -98,9 +141,10 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { builder.SetJumpTarget(2) // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] // data statck [ownerSignature, newMarginAmount] + builder.AddOp(vm.OP_DROP) builder.AddOp(vm.OP_DUP) cpAltStack(builder, 0) - builder.AddOp(vm.OP_DUP) + builder.AddOp(vm.OP_SWAP) builder.AddOp(vm.OP_SUB) builder.AddUint64(2) builder.AddOp(vm.OP_SWAP) @@ -146,6 +190,7 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { // alt stack [publicKey, creater, taxRate, nftAsset, owner, newMarginAsset, newMarginAmount] // data statck [1, newMarginAmount, newMarginAsset, 1, PROGRAM] builder.AddOp(vm.OP_CHECKOUTPUT) + builder.SetJumpTarget(5) return builder.Build() } @@ -179,43 +224,6 @@ func NewOffer(nftContract []byte) ([]byte, error) { return builder.Build() } -/* - init alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - init data stack [signature, buyerPublicKey, buyerScirpt] -*/ -func NewTransfer() ([]byte, error) { - builder := vmutil.NewBuilder() - - builder.AddUint64(2) - builder.AddOp(vm.OP_ROLL) - cpAltStack(builder, 6) - builder.AddOp(vm.OP_TXSIGHASH) - builder.AddOp(vm.OP_SWAP) - // alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] - // data stack [buyerPublicKey, buyerScirpt, ownerSignature, txSigHash, publicKey] - builder.AddOp(vm.OP_CHECKSIG) - builder.AddOp(vm.OP_VERIFY) - - swapAltStack(builder, 0, 2) - swapAltStack(builder, 0, 6) - - builder.AddUint64(0) - builder.AddUint64(1) - cpAltStack(builder, 3) - builder.AddUint64(1) - builder.AddOp(vm.OP_PROGRAM) - builder.AddOp(vm.OP_CHECKOUTPUT) - builder.AddOp(vm.OP_VERIFY) - - builder.AddUint64(1) - cpAltStack(builder, 0) - cpAltStack(builder, 1) - builder.AddUint64(1) - builder.AddOp(vm.OP_PROGRAM) - builder.AddOp(vm.OP_CHECKOUTPUT) - return builder.Build() -} - func swapAltStack(builder *vmutil.Builder, dataPos, AltPos uint64) { for i := uint64(0); i <= AltPos; i++ { builder.AddOp(vm.OP_FROMALTSTACK) diff --git a/nft/nft_test.go b/nft/nft_test.go index e82289495..dfdcacd61 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -56,13 +56,13 @@ func TestAddMargin(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("d51a48a7b5918de3cbf97de1a047af34fcb144c0308558a6ed5c4a12f4f338b9ccef23cd51937116412059569ba966cdc3c19fd58caa8aca4c2b9323e15cc90d"), + testutil.MustDecodeHexString("66d3b6d1422626213c39c2045bc8f5505333796c7c976e2152ca25f691248750fffc84b702d45fa17f8d74cc1beab2d782a664685dfcc95a291eaa1d5d05ad00"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("62fb14d988c57692a8860c25915e2fc7dbf4143388ede4200e79cc6dbf8751274cc0192d914137b9bb9f36b89d5e5f5909d041699f3d5fc1b27348e106a1520e"), + testutil.MustDecodeHexString("89ad84d8fdf7dbe5a21aaf1048ff9cb342bdb97c2c79d1428fe45e9fc1c31d980d0b9c642790931d6998d79d5a278439e4621795dd8a85627cf6a4fff363e506"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -115,15 +115,15 @@ func TestSubMargin(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("ba9772c480c349dc237f15e9606963224d7d1211072a79b4c34a045d19bb95a2bc20fba10f70097775a5b4e2a5c9f016ca96713fa19bdc5dfc0b4d21a9c3d407"), + testutil.MustDecodeHexString("9b6d86c36c3e86a576e3d1512074e2a45c0768541b57afc4b36e1f54d924b5aeba4b5176dde01f9a7360a6d06bd9711c8be58a2b7ec5005217522438bff9520a"), vm.Uint64Bytes(200000000), - vm.Uint64Bytes(1), + vm.Uint64Bytes(2), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("d7d82e40d5a6022aa2b7eb602ded566fa748e9549bd73146d7c2251401805f113ed2f5d76a5208ebfae989e5c7da37e976d59564bf05f9682b5057e163121407"), + testutil.MustDecodeHexString("ae5e2d806e49a418e7b952b132dcb95d26076302a44812ecd6076af26ac1377cc20bf66cdf6d560e944ffc62b27d3b589bff306bfce33e217f0f1d84ae07cd06"), vm.Uint64Bytes(200000000), - vm.Uint64Bytes(1), + vm.Uint64Bytes(2), } tx := types.NewTx(types.TxData{ @@ -148,7 +148,7 @@ func TestSubMargin(t *testing.T) { } func TestTransferNft(t *testing.T) { - contract, err := NewTransfer() + contract, err := NewContract(platformScript, marginFold) if err != nil { t.Fatal(err) } @@ -174,15 +174,17 @@ func TestTransferNft(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("2f78dd3131fec66074654ab6f5c8d18bd9e07937b176c55b74b019d1a1956446cbbfc7fd1d13411f17e3e7e81a83301129bb9e355514a2487dee5635e4b86504"), + testutil.MustDecodeHexString("060e8b5e0090709f02d3c4ba7f83e8f38c0661154f3a5c58d267d315fc734ba4e6bccaa2aef2d10fbaa980808fd4dc89faaef9d64627e061518f613766737d09"), buyerPublicKey, buyerScirpt, + vm.Uint64Bytes(3), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("b64f6a98f6bc5b35ed8f88fab7faa3700a25e574fbbe696b438fdcc486a15eb4bdad05c4509c2835bd0ca1e8dd615fcb4ca79599e68f2adde1211ae014750f0f"), + testutil.MustDecodeHexString("e05d5dc410721c307a7287c2705482a065b93fdb4f0925389db25fe132f216b2eb504ceb844dd462bdc3468ab233972a1ae33394fcf66b374fcc4935281b5b06"), buyerPublicKey, buyerScirpt, + vm.Uint64Bytes(3), } tx := types.NewTx(types.TxData{ @@ -410,12 +412,12 @@ func TestCancelOffer(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("4afb322c65d4d966b20de6a9fb891a926bb04fb9dcdcced8bf58b0caffbc0ed7798d6874f25bc34cec2ffe5a017fa10701d8c81812d174a10bd3e7a1fc5cb300"), + testutil.MustDecodeHexString("56b45f220874f271d7b130372ee5d5f3c86a3dd253a3a5fc0dfe3497591589604760449defe9f6bc48bac09dcedee22c948f7adee65f37715edb4301f3e3760c"), vm.Uint64Bytes(0), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("4f7b9b4f15dfba12e80789619d33491a7537a68667f75b6889d40aa7138c9c497d3aaff3f7a7830cf155562ecd2d500bbcd453d323bcb0926d0e91ea09f42507"), + testutil.MustDecodeHexString("1f591206a9a427e3ffe0c9f03cc971b60bc43511a0fff3a5d200a14fa9ef13c31c0219cc13e78f8b0b72adfdc1da3fc1e08483273f2de7f1210bb2f3f6d7dc00"), vm.Uint64Bytes(0), } From 363494a0ad198ad94b6cb425137ef7a249f1fb38 Mon Sep 17 00:00:00 2001 From: hyl <563807243@qq.com> Date: Tue, 23 Nov 2021 17:08:14 +0800 Subject: [PATCH 18/18] fix clause_selector except --- nft/nft.go | 13 +++++++++++++ nft/nft_test.go | 16 ++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/nft/nft.go b/nft/nft.go index bf7c57833..abb286190 100644 --- a/nft/nft.go +++ b/nft/nft.go @@ -18,6 +18,19 @@ func NewContract(platformScript []byte, marginFold uint64) ([]byte, error) { init alt stack [publicKey, creater, taxRate, nftAsset, owner, marginAsset, marginAmount] init data stack [signature, buyerPublicKey, buyerScirpt, selecter] */ + + // first check clause_selector for addMargin & subMargin + builder.AddOp(vm.OP_DUP) + builder.AddUint64(1) + builder.AddOp(vm.OP_EQUAL) + builder.AddUint64(2) + builder.AddOp(vm.OP_PICK) + cpAltStack(builder, 0) + builder.AddOp(vm.OP_LESSTHAN) + builder.AddOp(vm.OP_BOOLAND) + builder.AddOp(vm.OP_NOT) + builder.AddOp(vm.OP_VERIFY) + builder.AddOp(vm.OP_DUP) builder.AddUint64(3) builder.AddOp(vm.OP_EQUAL) diff --git a/nft/nft_test.go b/nft/nft_test.go index dfdcacd61..45cbd69f4 100644 --- a/nft/nft_test.go +++ b/nft/nft_test.go @@ -56,13 +56,13 @@ func TestAddMargin(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("66d3b6d1422626213c39c2045bc8f5505333796c7c976e2152ca25f691248750fffc84b702d45fa17f8d74cc1beab2d782a664685dfcc95a291eaa1d5d05ad00"), + testutil.MustDecodeHexString("6bdd6c340a50e65601b9e2b920109d6e58a0bc70ca709036a597afa3c5fd14ad191c48526c7f847f8158e5ceaf492b8eb1319ae7bcf81243e183a768a01f5a0f"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("89ad84d8fdf7dbe5a21aaf1048ff9cb342bdb97c2c79d1428fe45e9fc1c31d980d0b9c642790931d6998d79d5a278439e4621795dd8a85627cf6a4fff363e506"), + testutil.MustDecodeHexString("ca291761eb8c82c4f871ce73771d24ec1a2be9f1cb3223d1bbc1d0e1c1a7715e15691133c4064e30cf099a64302edb014b92e5808b7b60bbceb2347a021b3904"), vm.Uint64Bytes(300000000), vm.Uint64Bytes(1), } @@ -115,13 +115,13 @@ func TestSubMargin(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("9b6d86c36c3e86a576e3d1512074e2a45c0768541b57afc4b36e1f54d924b5aeba4b5176dde01f9a7360a6d06bd9711c8be58a2b7ec5005217522438bff9520a"), + testutil.MustDecodeHexString("022e7125afb47f4ff9238cf9665b166c75012ddcfcfef20df76224604c566e085972c470f7731d820c8fbc12b0c9603a8a620df4b4db91f4a6fc2cb37b07eb03"), vm.Uint64Bytes(200000000), vm.Uint64Bytes(2), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("ae5e2d806e49a418e7b952b132dcb95d26076302a44812ecd6076af26ac1377cc20bf66cdf6d560e944ffc62b27d3b589bff306bfce33e217f0f1d84ae07cd06"), + testutil.MustDecodeHexString("3725d8a8e5c6f8618dbbf0999f2cdcb40587165d0c6ee48744852a814866ae46b65817415f5f6f1dfe221b43c2d119edb8ec2a7b0b726a3585ecf1f243b6c20f"), vm.Uint64Bytes(200000000), vm.Uint64Bytes(2), } @@ -174,14 +174,14 @@ func TestTransferNft(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("060e8b5e0090709f02d3c4ba7f83e8f38c0661154f3a5c58d267d315fc734ba4e6bccaa2aef2d10fbaa980808fd4dc89faaef9d64627e061518f613766737d09"), + testutil.MustDecodeHexString("8cf7f6ec37a98eca9fd70b79f80052e9446e0a14edcb1e4ebdcff8f579f40e3cfd3bc9ffe15dc97614ba3dc1ee3e03f78c481be97e0d4c25b0d1ace1f446a509"), buyerPublicKey, buyerScirpt, vm.Uint64Bytes(3), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("e05d5dc410721c307a7287c2705482a065b93fdb4f0925389db25fe132f216b2eb504ceb844dd462bdc3468ab233972a1ae33394fcf66b374fcc4935281b5b06"), + testutil.MustDecodeHexString("2841414d808a5770ce154bc7f1b07ad7d7ea68c9f257bb5b824ec8d579d99d68f4fdcebdfdf9f4e6a553fba5ee9f54cefe4e6674d74022c671f38d96db93cf04"), buyerPublicKey, buyerScirpt, vm.Uint64Bytes(3), @@ -412,12 +412,12 @@ func TestCancelOffer(t *testing.T) { } arguments1 := [][]byte{ - testutil.MustDecodeHexString("56b45f220874f271d7b130372ee5d5f3c86a3dd253a3a5fc0dfe3497591589604760449defe9f6bc48bac09dcedee22c948f7adee65f37715edb4301f3e3760c"), + testutil.MustDecodeHexString("8a92ed02239357c5c083937686c441f0d3b16f5cb62261c2c8fa63af62286dc4f9bc617cf8f2e16df9c1965e2b85e0b4c0f543d327c7e5a158e9bfed14ad4e00"), vm.Uint64Bytes(0), } arguments2 := [][]byte{ - testutil.MustDecodeHexString("1f591206a9a427e3ffe0c9f03cc971b60bc43511a0fff3a5d200a14fa9ef13c31c0219cc13e78f8b0b72adfdc1da3fc1e08483273f2de7f1210bb2f3f6d7dc00"), + testutil.MustDecodeHexString("b3ae5a0119ac3b3c73c568ac144628433ee4c99c0464c93a5190e8c629af14ac6b81ddd9400be917256e2fdd9d0cd61eb7a53e96f4aac370b8446e6d8cf85603"), vm.Uint64Bytes(0), }