From 67e693ec252b0fffe837db9b67d5aa306616ebed Mon Sep 17 00:00:00 2001 From: Salvionied Date: Tue, 5 Dec 2023 23:29:55 +0100 Subject: [PATCH] Fix: Plutus Mints and burns and exUnits update for MintTags --- ApolloBuilder.go | 25 ++++- plutusencoder/plutus.go | 2 - tests/txBuilding/ApolloBuilder_test.go | 125 ++++++++++++++++++------- 3 files changed, 115 insertions(+), 37 deletions(-) diff --git a/ApolloBuilder.go b/ApolloBuilder.go index 99370e2..be329c7 100644 --- a/ApolloBuilder.go +++ b/ApolloBuilder.go @@ -57,6 +57,7 @@ type Apollo struct { redeemers []Redeemer.Redeemer redeemersToUTxO map[string]Redeemer.Redeemer stakeRedeemers map[string]Redeemer.Redeemer + mintRedeemers map[string]Redeemer.Redeemer mint []Unit collaterals []UTxO.UTxO Fee int64 @@ -110,7 +111,8 @@ func New(cc Base.ChainContext) *Apollo { FeePadding: 0, usedUtxos: make([]string, 0), referenceInputs: make([]TransactionInput.TransactionInput, 0), - referenceScripts: make([]PlutusData.ScriptHashable, 0)} + referenceScripts: make([]PlutusData.ScriptHashable, 0), + mintRedeemers: make(map[string]Redeemer.Redeemer)} } /* @@ -603,7 +605,8 @@ func (b *Apollo) MintAssets(mintUnit Unit) *Apollo { */ func (b *Apollo) MintAssetsWithRedeemer(mintUnit Unit, redeemer Redeemer.Redeemer) *Apollo { b.mint = append(b.mint, mintUnit) - b.redeemers = append(b.redeemers, redeemer) + b.mintRedeemers[mintUnit.PolicyId] = redeemer + b.isEstimateRequired = true return b } @@ -886,12 +889,23 @@ func (b *Apollo) updateExUnits() *Apollo { b.stakeRedeemers[k] = redeemer } } + for k, redeemer := range b.mintRedeemers { + key := fmt.Sprintf("%s:%d", Redeemer.RdeemerTagNames[redeemer.Tag], redeemer.Index) + if _, ok := estimated_execution_units[key]; ok { + redeemer.ExUnits = estimated_execution_units[key] + b.mintRedeemers[k] = redeemer + } + } for _, redeemer := range b.redeemersToUTxO { b.redeemers = append(b.redeemers, redeemer) } for _, redeemer := range b.stakeRedeemers { b.redeemers = append(b.redeemers, redeemer) } + for _, redeemer := range b.mintRedeemers { + b.redeemers = append(b.redeemers, redeemer) + + } } else { for _, redeemer := range b.redeemersToUTxO { b.redeemers = append(b.redeemers, redeemer) @@ -899,6 +913,10 @@ func (b *Apollo) updateExUnits() *Apollo { for _, redeemer := range b.stakeRedeemers { b.redeemers = append(b.redeemers, redeemer) } + for _, redeemer := range b.mintRedeemers { + b.redeemers = append(b.redeemers, redeemer) + } + } return b } @@ -1143,11 +1161,13 @@ Returns: func (b *Apollo) addChangeAndFee() (*Apollo, error) { burns := b.GetBurns() + mints := b.getMints() providedAmount := Value.Value{} for _, utxo := range b.preselectedUtxos { providedAmount = providedAmount.Add(utxo.Output.GetValue()) } providedAmount = providedAmount.Sub(burns) + providedAmount = providedAmount.Add(Value.SimpleValue(0, mints)) requestedAmount := Value.Value{} for _, payment := range b.payments { requestedAmount = requestedAmount.Add(payment.ToValue()) @@ -1235,7 +1255,6 @@ func (b *Apollo) CollectFrom( b.isEstimateRequired = true b.preselectedUtxos = append(b.preselectedUtxos, inputUtxo) b.usedUtxos = append(b.usedUtxos, inputUtxo.GetKey()) - b.redeemersToUTxO[hex.EncodeToString(inputUtxo.Input.TransactionId)+fmt.Sprint(inputUtxo.Input.Index)] = redeemer return b } diff --git a/plutusencoder/plutus.go b/plutusencoder/plutus.go index 9036214..b981176 100644 --- a/plutusencoder/plutus.go +++ b/plutusencoder/plutus.go @@ -270,8 +270,6 @@ func unmarshalPlutus(data *PlutusData.PlutusData, v interface{}, Plutusconstr ui reflect.ValueOf(v).Elem().Field(idx + 1).SetString(string(pAEl.Value.([]byte))) continue } - fmt.Println(tps.Field(idx + 1).Type.Kind()) - return fmt.Errorf("error: Bytes field is not a slice") } reflect.ValueOf(v).Elem().Field(idx + 1).Set(reflect.ValueOf(pAEl.Value)) case PlutusData.PlutusInt: diff --git a/tests/txBuilding/ApolloBuilder_test.go b/tests/txBuilding/ApolloBuilder_test.go index 1051337..2f0fe84 100644 --- a/tests/txBuilding/ApolloBuilder_test.go +++ b/tests/txBuilding/ApolloBuilder_test.go @@ -8,9 +8,15 @@ import ( "github.com/Salvionied/apollo" "github.com/Salvionied/apollo/serialization/Address" + "github.com/Salvionied/apollo/serialization/Asset" + "github.com/Salvionied/apollo/serialization/AssetName" "github.com/Salvionied/apollo/serialization/MultiAsset" "github.com/Salvionied/apollo/serialization/PlutusData" + "github.com/Salvionied/apollo/serialization/Policy" + "github.com/Salvionied/apollo/serialization/Redeemer" "github.com/Salvionied/apollo/serialization/Transaction" + "github.com/Salvionied/apollo/serialization/TransactionInput" + "github.com/Salvionied/apollo/serialization/TransactionOutput" "github.com/Salvionied/apollo/serialization/UTxO" "github.com/Salvionied/apollo/serialization/Value" "github.com/Salvionied/apollo/txBuilding/Backend/BlockFrostChainContext" @@ -252,20 +258,20 @@ func TestFakeBurnBalancing(t *testing.T) { } -// func TestScriptAddress(t *testing.T) { -// SC_CBOR := "5901ec01000032323232323232323232322223232533300a3232533300c002100114a066646002002444a66602400429404c8c94ccc040cdc78010018a5113330050050010033015003375c60260046eb0cc01cc024cc01cc024011200048040dd71980398048012400066e3cdd7198031804001240009110d48656c6c6f2c20576f726c642100149858c8014c94ccc028cdc3a400000226464a66602060240042930a99806a49334c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2065787065637465640016375c6020002601000a2a660169212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e7400163008004320033253330093370e900000089919299980798088010a4c2a66018921334c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2065787065637465640016375c601e002600e0062a660149212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e740016300700233001001480008888cccc01ccdc38008018061199980280299b8000448008c0380040080088c018dd5000918021baa0015734ae7155ceaab9e5573eae855d11" -// //resultingAddr := "addr1w8elsgw3y2cyzfzdup6tj42v0k7vvte57cjzvdzvp595epsljnl47" -// decoded_string, err := hex.DecodeString(SC_CBOR) -// if err != nil { -// t.Error(err) -// } -// p2Script := PlutusData.PlutusV2Script(decoded_string) -// hashOfScript := p2Script.Hash() -// if hex.EncodeToString(hashOfScript.Bytes()) != "f3f821d122b041244de074b9554c7dbcc62f34f62426344c0d0b4c86" { -// t.Error("Hash of script is not correct", hex.EncodeToString(hashOfScript.Bytes()), " != ", "f3f821d122b041244de074b9554c7dbcc62f34f62426344c0d0b4c86") -// } +func TestScriptAddress(t *testing.T) { + SC_CBOR := "5901ec01000032323232323232323232322223232533300a3232533300c002100114a066646002002444a66602400429404c8c94ccc040cdc78010018a5113330050050010033015003375c60260046eb0cc01cc024cc01cc024011200048040dd71980398048012400066e3cdd7198031804001240009110d48656c6c6f2c20576f726c642100149858c8014c94ccc028cdc3a400000226464a66602060240042930a99806a49334c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2065787065637465640016375c6020002601000a2a660169212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e7400163008004320033253330093370e900000089919299980798088010a4c2a66018921334c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2065787065637465640016375c601e002600e0062a660149212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e740016300700233001001480008888cccc01ccdc38008018061199980280299b8000448008c0380040080088c018dd5000918021baa0015734ae7155ceaab9e5573eae855d11" + //resultingAddr := "addr1w8elsgw3y2cyzfzdup6tj42v0k7vvte57cjzvdzvp595epsljnl47" + decoded_string, err := hex.DecodeString(SC_CBOR) + if err != nil { + t.Error(err) + } + p2Script := PlutusData.PlutusV2Script(decoded_string) + hashOfScript, _ := p2Script.Hash() + if hex.EncodeToString(hashOfScript.Bytes()) != "f3f821d122b041244de074b9554c7dbcc62f34f62426344c0d0b4c86" { + t.Error("Hash of script is not correct", hex.EncodeToString(hashOfScript.Bytes()), " != ", "f3f821d122b041244de074b9554c7dbcc62f34f62426344c0d0b4c86") + } -// } +} // func TestUnlock1Ada(t *testing.T) { // txHash := "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056" @@ -425,25 +431,6 @@ func TestFakeBurnBalancing(t *testing.T) { // } -// func TestSimpleBuild(t *testing.T) { -// cc := BlockFrostChainContext.NewBlockfrostChainContext("blockfrost_api_key", int(MAINNET), BLOCKFROST_BASE_URL_MAINNET) -// apollob := apollo.New(&cc) -// apollob, err := apollob. -// AddInputAddressFromBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu"). -// AddLoadedUTxOs(initUtxosDifferentiated()). -// PayToAddressBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", 10_000_000, nil). -// PayToAddressBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", -// 5_000_000, -// []apollo.Unit{{"00000000000000000000000000000000000000000000000000000000", "token0", 1}, {"00000000000000000000000000000000000000000000000000000000", "token2", 3}}, -// ).Complete() -// if err != nil { -// t.Error(err) -// } -// cborred, _ := cbor.Marshal(apollob.GetTx()) -// fmt.Println(apollob.GetTx().TransactionBody.CollateralReturn, apollob.GetTx().TransactionBody.Withdrawals) -// fmt.Println(hex.EncodeToString(cborred)) -// } - func TestFailedSubmissionThrows(t *testing.T) { cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") apollob := apollo.New(&cc) @@ -460,3 +447,77 @@ func TestFailedSubmissionThrows(t *testing.T) { t.Error("DIDNT THROW") } } + +func TestBurnPlutus(t *testing.T) { + cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") + decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + policy := Policy.PolicyId{Value: "279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f"} + testUtxo := UTxO.UTxO{ + Input: TransactionInput.TransactionInput{ + TransactionId: []byte("d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056"), + Index: 0, + }, + Output: TransactionOutput.SimpleTransactionOutput( + decoded_addr, + Value.SimpleValue(15000000, MultiAsset.MultiAsset[int64]{ + policy: Asset.Asset[int64]{AssetName.NewAssetNameFromString("TEST"): 1}, + })), + } + + apollob := apollo.New(&cc) + apollob, err := apollob. + AddLoadedUTxOs(testUtxo). + SetChangeAddress(decoded_addr). + MintAssetsWithRedeemer( + apollo.Unit{ + PolicyId: policy.String(), + Name: "TEST", + Quantity: int(-1), + }, + Redeemer.Redeemer{}, + ). + Complete() + if err != nil { + t.Error(err) + } + txBytes, err := apollob.GetTx().Bytes() + if hex.EncodeToString(txBytes) != "84a5008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536000181825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a00e2117b021a0002d04509a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa14454455354200b5820aed726f17f6c88739b6d5ba2e104b948bb81f6c46e8fc0809c120021c1e6e88ba203800581840000f6820000f5f6" { + t.Error("Tx is not correct", hex.EncodeToString(txBytes)) + } +} + +func TestMintPlutus(t *testing.T) { + cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") + decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + policy := Policy.PolicyId{Value: "279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f"} + testUtxo := UTxO.UTxO{ + Input: TransactionInput.TransactionInput{ + TransactionId: []byte("d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056"), + Index: 0, + }, + Output: TransactionOutput.SimpleTransactionOutput( + decoded_addr, + Value.SimpleValue(15000000, nil)), + } + + apollob := apollo.New(&cc) + apollob, err := apollob. + AddLoadedUTxOs(testUtxo). + SetChangeAddress(decoded_addr). + MintAssetsWithRedeemer( + apollo.Unit{ + PolicyId: policy.String(), + Name: "TEST", + Quantity: int(1), + }, + Redeemer.Redeemer{}, + ). + Complete() + if err != nil { + t.Error(err) + } + txBytes, err := apollob.GetTx().Bytes() + if hex.EncodeToString(txBytes) != "84a5008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536000181825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c9821a00e20ac7a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa1445445535401021a0002d6f909a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa14454455354010b5820aed726f17f6c88739b6d5ba2e104b948bb81f6c46e8fc0809c120021c1e6e88ba203800581840000f6820000f5f6" { + t.Error("Tx is not correct", hex.EncodeToString(txBytes)) + } +}