From 4f97a2b0581e69031b0d8b3efb4e342b3c53f114 Mon Sep 17 00:00:00 2001 From: Joaquin Hoyos Date: Sun, 4 Feb 2024 22:27:51 -0300 Subject: [PATCH] feat: add tx signing with both stake and payment key --- ApolloBuilder.go | 194 +++++++++--- ApolloBuilder_test.go | 365 +++++++++++++++++------ apollotypes/types.go | 166 +++++++++-- serialization/Certificate/Certificate.go | 13 + serialization/Key/Key.go | 2 - 5 files changed, 590 insertions(+), 150 deletions(-) diff --git a/ApolloBuilder.go b/ApolloBuilder.go index c9d28a8..ea6cdb0 100644 --- a/ApolloBuilder.go +++ b/ApolloBuilder.go @@ -337,7 +337,13 @@ func (b *Apollo) AddDatum(pd *PlutusData.PlutusData) *Apollo { Returns: *Apollo: A pointer to the modified Apollo instance with the payment and datum added. */ -func (b *Apollo) PayToContract(contractAddress Address.Address, pd *PlutusData.PlutusData, lovelace int, isInline bool, units ...Unit) *Apollo { +func (b *Apollo) PayToContract( + contractAddress Address.Address, + pd *PlutusData.PlutusData, + lovelace int, + isInline bool, + units ...Unit, +) *Apollo { if isInline { b = b.AddPayment(&Payment{lovelace, contractAddress, units, pd, nil, isInline}) } else if pd != nil { @@ -355,25 +361,40 @@ func (b *Apollo) PayToContract(contractAddress Address.Address, pd *PlutusData.P /* * - AddRequiredSignerFromBech32 decodes an address in Bech32 format and adds - its payment and staking parts as required signers. + AddRequiredSignerFromBech32 decodes an address in Bech32 format and adds + its payment and staking parts as required signers. + + Params: + + + address (string): The Bech32-encoded address to decode and add its parts as required signers. + + + addPaymentPart (bool): Indicates whether to add the payment part as a required signer. + - Params: - address (string): The Bech32-encoded address to decode and add its parts as required signers. - addPaymentPart (bool): Indicates whether to add the payment part as a required signer. addStakingPart (bool): Indicates whether to add the staking part as a required signer. Returns: *Apollo: A pointer to the modified Apollo instance with the required signers added. */ -func (b *Apollo) AddRequiredSignerFromBech32(address string, addPaymentPart, addStakingPart bool) *Apollo { +func (b *Apollo) AddRequiredSignerFromBech32( + address string, + addPaymentPart, addStakingPart bool, +) *Apollo { decoded_addr, _ := Address.DecodeAddress(address) if addPaymentPart { - b.requiredSigners = append(b.requiredSigners, serialization.PubKeyHash(decoded_addr.PaymentPart[0:28])) + b.requiredSigners = append( + b.requiredSigners, + serialization.PubKeyHash(decoded_addr.PaymentPart[0:28]), + ) } if addStakingPart { - b.requiredSigners = append(b.requiredSigners, serialization.PubKeyHash(decoded_addr.StakingPart[0:28])) + b.requiredSigners = append( + b.requiredSigners, + serialization.PubKeyHash(decoded_addr.StakingPart[0:28]), + ) } return b @@ -401,14 +422,23 @@ func (b *Apollo) AddRequiredSigner(pkh serialization.PubKeyHash) *Apollo { AddRequiredSignerFromAddress extracts the payment and staking parts from an address and adds them as required signers. Params: - address (Address.Address): The address from which to extract the parts and add them as required signers. - addPaymentPart (bool): Indicates whether to add the payment part as a required signer. - addStakingPart (bool): Indicates whether to add the staking part as a required signer. - Returns: - *Apollo: A pointer to the modified Apollo instance with the required signers added. + + address (Address.Address): The address from which to extract the parts and add them as required signers. + + + addPaymentPart (bool): Indicates whether to add the payment part as a required signer. + + + addStakingPart (bool): Indicates whether to add the staking part as a required signer. + + Returns: + *Apollo: A pointer to the modified Apollo instance with the required signers added. */ -func (b *Apollo) AddRequiredSignerFromAddress(address Address.Address, addPaymentPart, addStakingPart bool) *Apollo { +func (b *Apollo) AddRequiredSignerFromAddress( + address Address.Address, + addPaymentPart, addStakingPart bool, +) *Apollo { if addPaymentPart { pkh := serialization.PubKeyHash(address.PaymentPart) @@ -787,10 +817,14 @@ func (b *Apollo) setCollateral() (*Apollo, error) { if len(b.collaterals) > 0 { collateral_amount := 5_000_000 for _, utxo := range b.collaterals { - if int(utxo.Output.GetValue().GetCoin()) >= collateral_amount+1_000_000 && len(utxo.Output.GetValue().GetAssets()) <= 5 { + if int(utxo.Output.GetValue().GetCoin()) >= collateral_amount+1_000_000 && + len(utxo.Output.GetValue().GetAssets()) <= 5 { b.totalCollateral = collateral_amount return_amount := utxo.Output.GetValue().GetCoin() - int64(collateral_amount) - returnOutput := TransactionOutput.SimpleTransactionOutput(b.inputAddresses[0], Value.SimpleValue(return_amount, utxo.Output.GetValue().GetAssets())) + returnOutput := TransactionOutput.SimpleTransactionOutput( + b.inputAddresses[0], + Value.SimpleValue(return_amount, utxo.Output.GetValue().GetAssets()), + ) b.collateralReturn = &returnOutput } } @@ -805,9 +839,16 @@ func (b *Apollo) setCollateral() (*Apollo, error) { availableUtxos := b.getAvailableUtxos() collateral_amount := 5_000_000 for _, utxo := range availableUtxos { - if int(utxo.Output.GetValue().GetCoin()) >= collateral_amount && len(utxo.Output.GetValue().GetAssets()) <= 5 { + if int(utxo.Output.GetValue().GetCoin()) >= collateral_amount && + len(utxo.Output.GetValue().GetAssets()) <= 5 { return_amount := utxo.Output.GetValue().GetCoin() - int64(collateral_amount) - min_lovelace := Utils.MinLovelacePostAlonzo(TransactionOutput.SimpleTransactionOutput(b.inputAddresses[0], Value.SimpleValue(return_amount, utxo.Output.GetAmount().GetAssets())), b.Context) + min_lovelace := Utils.MinLovelacePostAlonzo( + TransactionOutput.SimpleTransactionOutput( + b.inputAddresses[0], + Value.SimpleValue(return_amount, utxo.Output.GetAmount().GetAssets()), + ), + b.Context, + ) if min_lovelace > return_amount && return_amount != 0 { continue } else if return_amount == 0 && len(utxo.Output.GetAmount().GetAssets()) == 0 { @@ -826,7 +867,13 @@ func (b *Apollo) setCollateral() (*Apollo, error) { for _, utxo := range availableUtxos { if int(utxo.Output.GetValue().GetCoin()) >= collateral_amount { return_amount := utxo.Output.GetValue().GetCoin() - int64(collateral_amount) - min_lovelace := Utils.MinLovelacePostAlonzo(TransactionOutput.SimpleTransactionOutput(b.inputAddresses[0], Value.SimpleValue(return_amount, utxo.Output.GetAmount().GetAssets())), b.Context) + min_lovelace := Utils.MinLovelacePostAlonzo( + TransactionOutput.SimpleTransactionOutput( + b.inputAddresses[0], + Value.SimpleValue(return_amount, utxo.Output.GetAmount().GetAssets()), + ), + b.Context, + ) if min_lovelace > return_amount && return_amount != 0 { continue } else if return_amount == 0 && len(utxo.Output.GetAmount().GetAssets()) == 0 { @@ -1019,7 +1066,11 @@ func (b *Apollo) Complete() (*Apollo, error) { } } for { - if selectedAmount.Greater(requestedAmount.Add(Value.Value{Am: Amount.Amount{}, Coin: 1_000_000, HasAssets: false})) { + if selectedAmount.Greater( + requestedAmount.Add( + Value.Value{Am: Amount.Amount{}, Coin: 1_000_000, HasAssets: false}, + ), + ) { break } if len(available_utxos) == 0 { @@ -1056,7 +1107,12 @@ func (b *Apollo) Complete() (*Apollo, error) { return nil, err } witnessSet := b.buildWitnessSet() - b.tx = &Transaction.Transaction{TransactionBody: body, TransactionWitnessSet: witnessSet, AuxiliaryData: b.auxiliaryData, Valid: true} + b.tx = &Transaction.Transaction{ + TransactionBody: body, + TransactionWitnessSet: witnessSet, + AuxiliaryData: b.auxiliaryData, + Valid: true, + } return b, nil } @@ -1075,7 +1131,10 @@ func (b *Apollo) Complete() (*Apollo, error) { bool: True if adding change would exceed the UTXO limit, false otherwise. */ func isOverUtxoLimit(change Value.Value, address Address.Address, b Base.ChainContext) bool { - txOutput := TransactionOutput.SimpleTransactionOutput(address, Value.SimpleValue(0, change.GetAssets())) + txOutput := TransactionOutput.SimpleTransactionOutput( + address, + Value.SimpleValue(0, change.GetAssets()), + ) encoded, _ := cbor.Marshal(txOutput) maxValSize, _ := strconv.Atoi(b.GetProtocolParams().MaxValSize) return len(encoded) > maxValSize @@ -1094,7 +1153,9 @@ func isOverUtxoLimit(change Value.Value, address Address.Address, b Base.ChainCo b: The ChainContext providing protocol parameters. Returns: - []*Payment: An array of payment objects, split if necessary to avoid exceeding the UTxO limit. + + + []*Payment: An array of payment objects, split if necessary to avoid exceeding the UTxO limit. */ func splitPayments(c Value.Value, a Address.Address, b Base.ChainContext) []*Payment { lovelace := c.GetCoin() @@ -1206,7 +1267,10 @@ func (b *Apollo) addChangeAndFee() (*Apollo, error) { requestedAmount.AddLovelace(b.Fee) change := providedAmount.Sub(requestedAmount) if change.GetCoin() < Utils.MinLovelacePostAlonzo( - TransactionOutput.SimpleTransactionOutput(b.inputAddresses[0], Value.SimpleValue(0, change.GetAssets())), + TransactionOutput.SimpleTransactionOutput( + b.inputAddresses[0], + Value.SimpleValue(0, change.GetAssets()), + ), b.Context, ) { if len(b.getAvailableUtxos()) == 0 { @@ -1371,14 +1435,27 @@ func (a *Apollo) SetWalletFromMnemonic(mnemonic string) (*Apollo, error) { //stake := stakingKeyPath.RootXprivKey.Bytes() signingKey := Key.SigningKey{Payload: signingKey_bytes} verificationKey := Key.VerificationKey{Payload: verificationKey_bytes} - stakeSigningKey := Key.StakeSigningKey{Payload: stakeSigningKey_bytes} - stakeVerificationKey := Key.StakeVerificationKey{Payload: stakeVerificationKey_bytes} + stakeSigningKey := Key.SigningKey{Payload: stakeSigningKey_bytes} + stakeVerificationKey := Key.VerificationKey{Payload: stakeVerificationKey_bytes} stakeVerKey := Key.VerificationKey{Payload: stakeVerificationKey_bytes} skh, _ := stakeVerKey.Hash() vkh, _ := verificationKey.Hash() - addr := Address.Address{StakingPart: skh[:], PaymentPart: vkh[:], Network: 1, AddressType: Address.KEY_KEY, HeaderByte: 0b00000001, Hrp: "addr"} - wallet := apollotypes.GenericWallet{SigningKey: signingKey, VerificationKey: verificationKey, Address: addr, StakeSigningKey: stakeSigningKey, StakeVerificationKey: stakeVerificationKey} + addr := Address.Address{ + StakingPart: skh[:], + PaymentPart: vkh[:], + Network: 1, + AddressType: Address.KEY_KEY, + HeaderByte: 0b00000001, + Hrp: "addr", + } + wallet := apollotypes.GenericWallet{ + SigningKey: signingKey, + VerificationKey: verificationKey, + Address: addr, + StakeSigningKey: stakeSigningKey, + StakeVerificationKey: stakeVerificationKey, + } a.wallet = &wallet return a, nil } @@ -1403,7 +1480,14 @@ func (a *Apollo) SetWalletFromKeypair(vkey string, skey string, network constant addr := Address.Address{} if network == constants.MAINNET { - addr = Address.Address{StakingPart: nil, PaymentPart: vkh[:], Network: 1, AddressType: Address.KEY_NONE, HeaderByte: 0b01100001, Hrp: "addr"} + addr = Address.Address{ + StakingPart: nil, + PaymentPart: vkh[:], + Network: 1, + AddressType: Address.KEY_NONE, + HeaderByte: 0b01100001, + Hrp: "addr", + } } else { addr = Address.Address{StakingPart: nil, PaymentPart: vkh[:], Network: 0, AddressType: Address.KEY_NONE, HeaderByte: 0b01100000, Hrp: "addr_test"} } @@ -1411,8 +1495,8 @@ func (a *Apollo) SetWalletFromKeypair(vkey string, skey string, network constant SigningKey: signingKey, VerificationKey: verificationKey, Address: addr, - StakeSigningKey: Key.StakeSigningKey{}, - StakeVerificationKey: Key.StakeVerificationKey{}, + StakeSigningKey: Key.SigningKey{}, + StakeVerificationKey: Key.VerificationKey{}, } a.wallet = &wallet return a @@ -1471,7 +1555,10 @@ func (b *Apollo) SetWalletAsChangeAddress() *Apollo { *Apollo: A pointer to the Apollo object with the transaction signed. */ func (b *Apollo) Sign() *Apollo { - signatures := b.wallet.SignTx(*b.tx) + usedUtxos := make([]UTxO.UTxO, len(b.preselectedUtxos)+len(b.collaterals)) + usedUtxos = append(usedUtxos, b.preselectedUtxos...) + usedUtxos = append(usedUtxos, b.collaterals...) + signatures := b.wallet.SignTx(*b.tx, usedUtxos) b.tx.TransactionWitnessSet = signatures return b } @@ -1499,7 +1586,10 @@ func (b *Apollo) SignWithSkey(vkey Key.VerificationKey, skey Key.SigningKey) (*A if err != nil { return b, err } - witness_set.VkeyWitnesses = append(witness_set.VkeyWitnesses, VerificationKeyWitness.VerificationKeyWitness{Vkey: vkey, Signature: signature}) + witness_set.VkeyWitnesses = append( + witness_set.VkeyWitnesses, + VerificationKeyWitness.VerificationKeyWitness{Vkey: vkey, Signature: signature}, + ) b.GetTx().TransactionWitnessSet = witness_set return b, nil } @@ -1573,7 +1663,9 @@ func (b *Apollo) UtxoFromRef(txHash string, txIndex int) *UTxO.UTxO { Returns: *Apollo: A pointer to the modified Apollo instance with the added verification key witness. */ -func (b *Apollo) AddVerificationKeyWitness(vkw VerificationKeyWitness.VerificationKeyWitness) *Apollo { +func (b *Apollo) AddVerificationKeyWitness( + vkw VerificationKeyWitness.VerificationKeyWitness, +) *Apollo { b.tx.TransactionWitnessSet.VkeyWitnesses = append(b.tx.TransactionWitnessSet.VkeyWitnesses, vkw) return b } @@ -1683,11 +1775,13 @@ func (b *Apollo) GetUsedUTxOs() []string { /* * - SetEstimationExUnitsRequired enables the estimation of execution units - for the transaction. + SetEstimationExUnitsRequired enables the estimation of execution units + for the transaction. - Returns: - *Apollo: A pointer to the modified Apollo instance with execution units estimation enabled. + Returns: + + + *Apollo: A pointer to the modified Apollo instance with execution units estimation enabled. */ func (b *Apollo) SetEstimationExUnitsRequired() *Apollo { b.isEstimateRequired = true @@ -1722,14 +1816,20 @@ func (b *Apollo) AddReferenceInput(txHash string, index int) *Apollo { DisableExecutionUnitsEstimation disables the estimation of execution units for the transaction. Returns: - *Apollo: A pointer to the modified Apollo instance with execution units estimation disabled. + + + *Apollo: A pointer to the modified Apollo instance with execution units estimation disabled. */ func (b *Apollo) DisableExecutionUnitsEstimation() *Apollo { b.isEstimateRequired = false return b } -func (b *Apollo) AddWithdrawal(address Address.Address, amount int, redeemerData PlutusData.PlutusData) *Apollo { +func (b *Apollo) AddWithdrawal( + address Address.Address, + amount int, + redeemerData PlutusData.PlutusData, +) *Apollo { if b.withdrawals == nil { newWithdrawal := Withdrawal.New() b.withdrawals = &newWithdrawal @@ -1737,7 +1837,10 @@ func (b *Apollo) AddWithdrawal(address Address.Address, amount int, redeemerData var stakeAddr [29]byte stakeAddr[0] = address.HeaderByte if len(address.StakingPart) != 28 { - fmt.Printf("AddWithdrawal: address has invalid or missing staking part: %v\n", address.StakingPart) + fmt.Printf( + "AddWithdrawal: address has invalid or missing staking part: %v\n", + address.StakingPart, + ) } copy(stakeAddr[1:], address.StakingPart) err := b.withdrawals.Add(stakeAddr, amount) @@ -1778,7 +1881,12 @@ func (b *Apollo) CompleteExact(fee int) (*Apollo, error) { return nil, err } witnessSet := b.buildWitnessSet() - b.tx = &Transaction.Transaction{TransactionBody: body, TransactionWitnessSet: witnessSet, AuxiliaryData: b.auxiliaryData, Valid: true} + b.tx = &Transaction.Transaction{ + TransactionBody: body, + TransactionWitnessSet: witnessSet, + AuxiliaryData: b.auxiliaryData, + Valid: true, + } return b, nil } diff --git a/ApolloBuilder_test.go b/ApolloBuilder_test.go index c9d45a6..5b63ae7 100644 --- a/ApolloBuilder_test.go +++ b/ApolloBuilder_test.go @@ -90,7 +90,11 @@ func TestEnsureTxIsBalanced(t *testing.T) { inputVal := Value.SimpleValue(0, MultiAsset.MultiAsset[int64]{}) for _, input := range apollob.GetTx().TransactionBody.Inputs { for _, utxo := range utxos { - if utxo.GetKey() == fmt.Sprintf("%s:%d", hex.EncodeToString(input.TransactionId), input.Index) { + if utxo.GetKey() == fmt.Sprintf( + "%s:%d", + hex.EncodeToString(input.TransactionId), + input.Index, + ) { //fmt.Println("INPUT", idx, utxo) inputVal = inputVal.Add(utxo.Output.GetAmount()) } @@ -140,12 +144,15 @@ func TestComplexTxBuild(t *testing.T) { } utxos = append(utxos, loadedUtxo) } - decodedAddress, _ := Address.DecodeAddress("addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4") + decodedAddress, _ := Address.DecodeAddress( + "addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4", + ) apollob = apollob.AddInputAddressFromBech32(userAddress).AddLoadedUTxOs(utxos...). PayToContract(decodedAddress, &pd, 4000000, false, - apollo.NewUnit("279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f", "SNEK", 10416)). + apollo.NewUnit("279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f", "SNEK", 10416), + ). PayToAddressBech32("addr1qxajla3qcrwckzkur8n0lt02rg2sepw3kgkstckmzrz4ccfm3j9pqrqkea3tns46e3qy2w42vl8dvvue8u45amzm3rjqvv2nxh", int(2_000_000)). SetTtl(0 + 300). SetValidityStart(0) @@ -158,7 +165,11 @@ func TestComplexTxBuild(t *testing.T) { inputVal := Value.SimpleValue(0, MultiAsset.MultiAsset[int64]{}) for _, input := range apollob.GetTx().TransactionBody.Inputs { for _, utxo := range utxos { - if utxo.GetKey() == fmt.Sprintf("%s:%d", hex.EncodeToString(input.TransactionId), input.Index) { + if utxo.GetKey() == fmt.Sprintf( + "%s:%d", + hex.EncodeToString(input.TransactionId), + input.Index, + ) { //fmt.Println("INPUT", idx, utxo) inputVal = inputVal.Add(utxo.Output.GetAmount()) } @@ -213,12 +224,15 @@ func TestFakeBurnBalancing(t *testing.T) { } utxos = append(utxos, loadedUtxo) } - decodedAddress, _ := Address.DecodeAddress("addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4") + decodedAddress, _ := Address.DecodeAddress( + "addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4", + ) apollob = apollob.AddInputAddressFromBech32(userAddress).AddLoadedUTxOs(utxos...). PayToContract(decodedAddress, &pd, 4000000, false, - apollo.NewUnit("279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f", "SNEK", 10416)). + apollo.NewUnit("279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f", "SNEK", 10416), + ). PayToAddressBech32("addr1qxajla3qcrwckzkur8n0lt02rg2sepw3kgkstckmzrz4ccfm3j9pqrqkea3tns46e3qy2w42vl8dvvue8u45amzm3rjqvv2nxh", int(2_000_000)). SetTtl(0 + 300). SetValidityStart(0).MintAssets( @@ -235,7 +249,11 @@ func TestFakeBurnBalancing(t *testing.T) { inputVal := Value.SimpleValue(0, MultiAsset.MultiAsset[int64]{}) for _, input := range apollob.GetTx().TransactionBody.Inputs { for _, utxo := range utxos { - if utxo.GetKey() == fmt.Sprintf("%s:%d", hex.EncodeToString(input.TransactionId), input.Index) { + if utxo.GetKey() == fmt.Sprintf( + "%s:%d", + hex.EncodeToString(input.TransactionId), + input.Index, + ) { //fmt.Println("INPUT", idx, utxo) inputVal = inputVal.Add(utxo.Output.GetAmount()) } @@ -269,8 +287,15 @@ func TestScriptAddress(t *testing.T) { } 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") + if hex.EncodeToString( + hashOfScript.Bytes(), + ) != "f3f821d122b041244de074b9554c7dbcc62f34f62426344c0d0b4c86" { + t.Error( + "Hash of script is not correct", + hex.EncodeToString(hashOfScript.Bytes()), + " != ", + "f3f821d122b041244de074b9554c7dbcc62f34f62426344c0d0b4c86", + ) } } @@ -434,7 +459,11 @@ func TestScriptAddress(t *testing.T) { // } func TestFailedSubmissionThrows(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) apollob := apollo.New(&cc) apollob, err := apollob. AddInputAddressFromBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu"). @@ -451,13 +480,21 @@ func TestFailedSubmissionThrows(t *testing.T) { } func TestBurnPlutus(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + 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, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 0, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -483,19 +520,29 @@ func TestBurnPlutus(t *testing.T) { t.Error(err) } txBytes, err := apollob.GetTx().Bytes() - if hex.EncodeToString(txBytes) != "84a5008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536000181825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a00e2117b021a0002d04509a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa14454455354200b5820aed726f17f6c88739b6d5ba2e104b948bb81f6c46e8fc0809c120021c1e6e88ba203800581840000f6820000f5f6" { + 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") + 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, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 0, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -519,19 +566,29 @@ func TestMintPlutus(t *testing.T) { t.Error(err) } txBytes, err := apollob.GetTx().Bytes() - if hex.EncodeToString(txBytes) != "84a5008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536000181825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c9821a00e20ac7a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa1445445535401021a0002d6f909a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa14454455354010b5820aed726f17f6c88739b6d5ba2e104b948bb81f6c46e8fc0809c120021c1e6e88ba203800581840000f6820000f5f6" { + if hex.EncodeToString( + txBytes, + ) != "84a5008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536000181825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c9821a00e20ac7a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa1445445535401021a0002d6f909a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa14454455354010b5820aed726f17f6c88739b6d5ba2e104b948bb81f6c46e8fc0809c120021c1e6e88ba203800581840000f6820000f5f6" { t.Error("Tx is not correct", hex.EncodeToString(txBytes)) } } func TestMintPlutusWithPayment(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + 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, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 0, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -562,32 +619,50 @@ func TestMintPlutusWithPayment(t *testing.T) { t.Error(err) } txBytes, err := apollob.GetTx().Bytes() - if hex.EncodeToString(txBytes) != "84a5008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536000182825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c9821a00151c56a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa1445445535401825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a00cce345021a0002e22509a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa14454455354010b5820aed726f17f6c88739b6d5ba2e104b948bb81f6c46e8fc0809c120021c1e6e88ba203800581840000f6820000f5f6" { + if hex.EncodeToString( + txBytes, + ) != "84a5008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536000182825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c9821a00151c56a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa1445445535401825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a00cce345021a0002e22509a1581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa14454455354010b5820aed726f17f6c88739b6d5ba2e104b948bb81f6c46e8fc0809c120021c1e6e88ba203800581840000f6820000f5f6" { t.Error("Tx is not correct", hex.EncodeToString(txBytes)) } } func TestGetWallet(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) apollob := apollo.New(&cc) wall := apollob.GetWallet() if wall != nil { t.Error("Wallet should be nil") } - apollob = apollob.SetWalletFromBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + apollob = apollob.SetWalletFromBech32( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) wallet := apollob.GetWallet() - if wallet.GetAddress().String() != "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu" { + if wallet.GetAddress(). + String() != + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu" { t.Error("Wallet address is not correct") } } func TestAddInputs(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) testUtxo := UTxO.UTxO{ Input: TransactionInput.TransactionInput{ - TransactionId: []byte("d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056"), - Index: 0, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 0, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -606,12 +681,20 @@ func TestAddInputs(t *testing.T) { } func TestConsumeUtxo(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) testUtxo := UTxO.UTxO{ Input: TransactionInput.TransactionInput{ - TransactionId: []byte("d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056"), - Index: 0, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 0, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -619,8 +702,10 @@ func TestConsumeUtxo(t *testing.T) { } biAdaUtxo := UTxO.UTxO{ Input: TransactionInput.TransactionInput{ - TransactionId: []byte("d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056"), - Index: 1, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 1, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -631,7 +716,9 @@ func TestConsumeUtxo(t *testing.T) { apollob = apollob.SetChangeAddress(decoded_addr). ConsumeUTxO(testUtxo, apollo.NewPayment("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", 2_000_000, nil), - apollo.NewPayment("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", 2_000_000, nil)).AddLoadedUTxOs(biAdaUtxo) + apollo.NewPayment("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", 2_000_000, nil), + ). + AddLoadedUTxOs(biAdaUtxo) built, err := apollob.Complete() if err != nil { t.Error(err) @@ -654,12 +741,20 @@ func TestConsumeUtxo(t *testing.T) { } func TestConsumeAssetsFromUtxo(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) testUtxo := UTxO.UTxO{ Input: TransactionInput.TransactionInput{ - TransactionId: []byte("d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056"), - Index: 0, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 0, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -671,8 +766,10 @@ func TestConsumeAssetsFromUtxo(t *testing.T) { } biAdaUtxo := UTxO.UTxO{ Input: TransactionInput.TransactionInput{ - TransactionId: []byte("d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056"), - Index: 1, + TransactionId: []byte( + "d5d1f7c223dc88bb41474af23b685e0247307e94e715ef5e62f325ac94f73056", + ), + Index: 1, }, Output: TransactionOutput.SimpleTransactionOutput( decoded_addr, @@ -682,7 +779,9 @@ func TestConsumeAssetsFromUtxo(t *testing.T) { apollob := apollo.New(&cc) apollob = apollob.SetChangeAddress(decoded_addr). ConsumeAssetsFromUtxo(testUtxo, - apollo.NewPayment("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", 2_000_000, []apollo.Unit{apollo.NewUnit("279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f", "TEST", 1)})).AddLoadedUTxOs(biAdaUtxo) + apollo.NewPayment("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", 2_000_000, []apollo.Unit{apollo.NewUnit("279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f", "TEST", 1)}), + ). + AddLoadedUTxOs(biAdaUtxo) built, err := apollob.Complete() if err != nil { t.Error(err) @@ -705,7 +804,9 @@ func TestConsumeAssetsFromUtxo(t *testing.T) { } } -var decoded_addr, _ = Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") +var decoded_addr, _ = Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", +) var InputUtxo = UTxO.UTxO{ Input: TransactionInput.TransactionInput{ @@ -718,8 +819,14 @@ var InputUtxo = UTxO.UTxO{ } func TestPayToContract(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) datum := PlutusData.PlutusData{ TagNr: 121, PlutusDataType: PlutusData.PlutusBytes, @@ -767,15 +874,23 @@ func TestPayToContract(t *testing.T) { t.Error("Tx is not correct", built.GetTx().TransactionBody.Outputs[1].GetDatum().TagNr) } txBytes, _ := built.GetTx().Bytes() - if hex.EncodeToString(txBytes) != "84a4008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536010183835839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a000f4240582037ead362f4ab7844a8416b045caa46a91066d391c16ae4d4a81557f14f7a0984a3005839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c9011a000f4240028201d81850d8794d48656c6c6f2c20576f726c6421825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a00c371ff021a0002eb410b5820e3ba8d5e90fa0152fc652eb7e2e8dfd9efa06ce2abd002e69c7b5f8a51be8cd7a1049fd8794d48656c6c6f2c20576f726c6421fff5f6" { + if hex.EncodeToString( + txBytes, + ) != "84a4008182584064356431663763323233646338386262343134373461663233623638356530323437333037653934653731356566356536326633323561633934663733303536010183835839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a000f4240582037ead362f4ab7844a8416b045caa46a91066d391c16ae4d4a81557f14f7a0984a3005839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c9011a000f4240028201d81850d8794d48656c6c6f2c20576f726c6421825839010a59337f7b3a913424d7f7a151401e052642b68e948d8cacadc6372016a9999419cc5a61ca62da81e378d7538213a3715a6b858c948c69c91a00c371ff021a0002eb410b5820e3ba8d5e90fa0152fc652eb7e2e8dfd9efa06ce2abd002e69c7b5f8a51be8cd7a1049fd8794d48656c6c6f2c20576f726c6421fff5f6" { t.Error("Tx is not correct", hex.EncodeToString(txBytes)) } } func TestRequiredSigner(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(InputUtxo). AddRequiredSignerFromAddress(decoded_addr, true, true) @@ -786,10 +901,18 @@ func TestRequiredSigner(t *testing.T) { if len(built.GetTx().TransactionBody.RequiredSigners) != 2 { t.Error("Tx is not correct") } - if hex.EncodeToString(built.GetTx().TransactionBody.RequiredSigners[0][:]) != hex.EncodeToString(decoded_addr.PaymentPart) { + if hex.EncodeToString( + built.GetTx().TransactionBody.RequiredSigners[0][:], + ) != hex.EncodeToString( + decoded_addr.PaymentPart, + ) { t.Error("Tx is not correct") } - if hex.EncodeToString(built.GetTx().TransactionBody.RequiredSigners[1][:]) != hex.EncodeToString(decoded_addr.StakingPart) { + if hex.EncodeToString( + built.GetTx().TransactionBody.RequiredSigners[1][:], + ) != hex.EncodeToString( + decoded_addr.StakingPart, + ) { t.Error("Tx is not correct") } apollob = apollo.New(&cc) @@ -802,10 +925,18 @@ func TestRequiredSigner(t *testing.T) { if len(built.GetTx().TransactionBody.RequiredSigners) != 2 { t.Error("Tx is not correct") } - if hex.EncodeToString(built.GetTx().TransactionBody.RequiredSigners[0][:]) != hex.EncodeToString(decoded_addr.PaymentPart) { + if hex.EncodeToString( + built.GetTx().TransactionBody.RequiredSigners[0][:], + ) != hex.EncodeToString( + decoded_addr.PaymentPart, + ) { t.Error("Tx is not correct") } - if hex.EncodeToString(built.GetTx().TransactionBody.RequiredSigners[1][:]) != hex.EncodeToString(decoded_addr.StakingPart) { + if hex.EncodeToString( + built.GetTx().TransactionBody.RequiredSigners[1][:], + ) != hex.EncodeToString( + decoded_addr.StakingPart, + ) { t.Error("Tx is not correct") } @@ -819,7 +950,11 @@ func TestRequiredSigner(t *testing.T) { if len(built.GetTx().TransactionBody.RequiredSigners) != 1 { t.Error("Tx is not correct") } - if hex.EncodeToString(built.GetTx().TransactionBody.RequiredSigners[0][:]) != hex.EncodeToString(decoded_addr.PaymentPart) { + if hex.EncodeToString( + built.GetTx().TransactionBody.RequiredSigners[0][:], + ) != hex.EncodeToString( + decoded_addr.PaymentPart, + ) { t.Error("Tx is not correct") } } @@ -843,10 +978,19 @@ var collateralUtxo2 = UTxO.UTxO{ Value.SimpleValue(10_000_000, nil))} func TestFeePadding(t *testing.T) { - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) - apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(InputUtxo).PayToContract(decoded_addr, nil, 1_000_000, false).SetFeePadding(500_000) + apollob = apollob.SetChangeAddress(decoded_addr). + AddLoadedUTxOs(InputUtxo). + PayToContract(decoded_addr, nil, 1_000_000, false). + SetFeePadding(500_000) built, err := apollob.Complete() if err != nil { t.Error(err) @@ -860,17 +1004,32 @@ func TestFeePadding(t *testing.T) { if built.GetTx().TransactionBody.Outputs[1].Lovelace() != 13316359 { t.Error("Tx is not correct", built.GetTx().TransactionBody.Outputs[1].Lovelace()) } - if built.GetTx().TransactionBody.Outputs[0].IsPostAlonzo && built.GetTx().TransactionBody.Outputs[0].GetDatumHash() != nil { - t.Error("Tx is not correct", built.GetTx().TransactionBody.Outputs[0].GetDatumHash(), built.GetTx().TransactionBody.Outputs[0].IsPostAlonzo) + if built.GetTx().TransactionBody.Outputs[0].IsPostAlonzo && + built.GetTx().TransactionBody.Outputs[0].GetDatumHash() != nil { + t.Error( + "Tx is not correct", + built.GetTx().TransactionBody.Outputs[0].GetDatumHash(), + built.GetTx().TransactionBody.Outputs[0].IsPostAlonzo, + ) } } func TestSetCollateral(t *testing.T) { // full 5 ada collateral - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) - apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(InputUtxo).PayToContract(decoded_addr, nil, 1_000_000, false).SetFeePadding(500_000).AddCollateral(collateralUtxo) + apollob = apollob.SetChangeAddress(decoded_addr). + AddLoadedUTxOs(InputUtxo). + PayToContract(decoded_addr, nil, 1_000_000, false). + SetFeePadding(500_000). + AddCollateral(collateralUtxo) built, err := apollob.Complete() if err != nil { t.Error(err) @@ -882,10 +1041,20 @@ func TestSetCollateral(t *testing.T) { func TestCollateralwithReturn(t *testing.T) { // full 5 ada collateral - cc := BlockFrostChainContext.NewBlockfrostChainContext(BLOCKFROST_BASE_URL_MAINNET, int(MAINNET), "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT") - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + cc := BlockFrostChainContext.NewBlockfrostChainContext( + BLOCKFROST_BASE_URL_MAINNET, + int(MAINNET), + "mainnetVueasSgKfYhM4PQBq0UGipAyHBpbX4oT", + ) + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) - apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(InputUtxo).PayToContract(decoded_addr, nil, 1_000_000, false).SetFeePadding(500_000).AddCollateral(collateralUtxo2) + apollob = apollob.SetChangeAddress(decoded_addr). + AddLoadedUTxOs(InputUtxo). + PayToContract(decoded_addr, nil, 1_000_000, false). + SetFeePadding(500_000). + AddCollateral(collateralUtxo2) built, err := apollob.Complete() if err != nil { t.Error(err) @@ -903,7 +1072,9 @@ func TestCollateralwithReturn(t *testing.T) { func TestRedeemerCollect(t *testing.T) { cc := apollo.NewEmptyBackend() - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) redeemer := Redeemer.Redeemer{ Tag: Redeemer.SPEND, @@ -920,7 +1091,8 @@ func TestRedeemerCollect(t *testing.T) { utxos := testutils.InitUtxosDifferentiated() apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(utxos...). - CollectFrom(InputUtxo, redeemer).AttachDatum(&datum).AttachV1Script([]byte("Hello, World!")).SetEstimationExUnitsRequired() + CollectFrom(InputUtxo, redeemer). + AttachDatum(&datum).AttachV1Script([]byte("Hello, World!")).SetEstimationExUnitsRequired() built, err := apollob.Complete() if err != nil { t.Error(err) @@ -979,9 +1151,12 @@ func TestRedeemerCollect(t *testing.T) { func TestAddSameScriptTwiceV1(t *testing.T) { cc := apollo.NewEmptyBackend() utxos := testutils.InitUtxosDifferentiated() - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) - apollob = apollob.AttachV1Script([]byte("Hello, World!")).AttachV1Script([]byte("Hello, World!")) + apollob = apollob.AttachV1Script([]byte("Hello, World!")). + AttachV1Script([]byte("Hello, World!")) apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(utxos...) built, err := apollob.Complete() if err != nil { @@ -996,9 +1171,12 @@ func TestAddSameScriptTwiceV1(t *testing.T) { func TestAddSameScriptTwiceV2(t *testing.T) { cc := apollo.NewEmptyBackend() utxos := testutils.InitUtxosDifferentiated() - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) - apollob = apollob.AttachV2Script([]byte("Hello, World!")).AttachV2Script([]byte("Hello, World!")) + apollob = apollob.AttachV2Script([]byte("Hello, World!")). + AttachV2Script([]byte("Hello, World!")) apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(utxos...) built, err := apollob.Complete() if err != nil { @@ -1012,12 +1190,15 @@ func TestAddSameScriptTwiceV2(t *testing.T) { func TestSetChangeAddressBech32(t *testing.T) { cc := apollo.NewEmptyBackend() apollob := apollo.New(&cc) - apollob = apollob.SetChangeAddressBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu").AddInput(InputUtxo) + apollob = apollob.SetChangeAddressBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu"). + AddInput(InputUtxo) built, err := apollob.Complete() if err != nil { t.Error(err) } - if built.GetTx().TransactionBody.Outputs[0].GetAddress().String() != "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu" { + if built.GetTx().TransactionBody.Outputs[0].GetAddress(). + String() != + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu" { t.Error("Tx is not correct") } } @@ -1025,12 +1206,16 @@ func TestSetChangeAddressBech32(t *testing.T) { func TestSetWalletFromBech32(t *testing.T) { cc := apollo.NewEmptyBackend() apollob := apollo.New(&cc) - apollob = apollob.SetWalletFromBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu").SetWalletAsChangeAddress().AddInput(InputUtxo) + apollob = apollob.SetWalletFromBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu"). + SetWalletAsChangeAddress(). + AddInput(InputUtxo) built, err := apollob.Complete() if err != nil { t.Error(err) } - if built.GetTx().TransactionBody.Outputs[0].GetAddress().String() != "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu" { + if built.GetTx().TransactionBody.Outputs[0].GetAddress(). + String() != + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu" { t.Error("Tx is not correct") } } @@ -1038,20 +1223,29 @@ func TestSetWalletFromBech32(t *testing.T) { func TestRefInput(t *testing.T) { cc := apollo.NewEmptyBackend() apollob := apollo.New(&cc) - apollob = apollob.SetWalletFromBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu").SetWalletAsChangeAddress().AddInput(InputUtxo). - AddReferenceInput(hex.EncodeToString(InputUtxo.Input.TransactionId), 0).AddCollateral(collateralUtxo) + apollob = apollob.SetWalletFromBech32("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu"). + SetWalletAsChangeAddress(). + AddInput(InputUtxo). + AddReferenceInput(hex.EncodeToString(InputUtxo.Input.TransactionId), 0). + AddCollateral(collateralUtxo) built, err := apollob.Complete() if err != nil { t.Error(err) } - if hex.EncodeToString(built.GetTx().TransactionBody.ReferenceInputs[0].TransactionId) != hex.EncodeToString(InputUtxo.Input.TransactionId) { + if hex.EncodeToString( + built.GetTx().TransactionBody.ReferenceInputs[0].TransactionId, + ) != hex.EncodeToString( + InputUtxo.Input.TransactionId, + ) { t.Error("Tx is not correct") } } func TestExactComplete(t *testing.T) { cc := apollo.NewEmptyBackend() - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) redeemer := Redeemer.Redeemer{ Tag: Redeemer.SPEND, @@ -1068,7 +1262,8 @@ func TestExactComplete(t *testing.T) { utxos := testutils.InitUtxosDifferentiated() apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(utxos...). - CollectFrom(InputUtxo, redeemer).AttachDatum(&datum).AttachV1Script([]byte("Hello, World!")).SetEstimationExUnitsRequired() + CollectFrom(InputUtxo, redeemer). + AttachDatum(&datum).AttachV1Script([]byte("Hello, World!")).SetEstimationExUnitsRequired() built, err := apollob.CompleteExact(200_000) if err != nil { t.Error(err) @@ -1125,7 +1320,9 @@ func TestExactComplete(t *testing.T) { func TestCongestedBuild(t *testing.T) { cc := apollo.NewEmptyBackend() - decoded_addr, _ := Address.DecodeAddress("addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu") + decoded_addr, _ := Address.DecodeAddress( + "addr1qy99jvml0vafzdpy6lm6z52qrczjvs4k362gmr9v4hrrwgqk4xvegxwvtfsu5ck6s83h346nsgf6xu26dwzce9yvd8ysd2seyu", + ) apollob := apollo.New(&cc) utxos := testutils.InitUtxosCongested() apollob = apollob.SetChangeAddress(decoded_addr).AddLoadedUTxOs(utxos...). diff --git a/apollotypes/types.go b/apollotypes/types.go index 25dd4c5..ded16db 100644 --- a/apollotypes/types.go +++ b/apollotypes/types.go @@ -1,19 +1,26 @@ package apollotypes import ( + "bytes" + "github.com/Salvionied/apollo/serialization" serAddress "github.com/Salvionied/apollo/serialization/Address" "github.com/Salvionied/apollo/serialization/Key" "github.com/Salvionied/apollo/serialization/Transaction" "github.com/Salvionied/apollo/serialization/TransactionWitnessSet" + "github.com/Salvionied/apollo/serialization/UTxO" "github.com/Salvionied/apollo/serialization/VerificationKeyWitness" "github.com/Salvionied/apollo/txBuilding/Backend/Base" ) type Wallet interface { GetAddress() *serAddress.Address - SignTx(tx Transaction.Transaction) TransactionWitnessSet.TransactionWitnessSet + SignTx( + tx Transaction.Transaction, + usedUtxos []UTxO.UTxO, + ) TransactionWitnessSet.TransactionWitnessSet PkeyHash() serialization.PubKeyHash + SkeyHash() serialization.PubKeyHash //SignMessage(address serAddress.Address, message []uint8) []uint8 } @@ -21,7 +28,9 @@ type ExternalWallet struct { Address serAddress.Address } -/** +/* +* + GetAddress returns the address associated with an external wallet. Returns: @@ -31,22 +40,31 @@ func (ew *ExternalWallet) GetAddress() *serAddress.Address { return &ew.Address } -/** +/* +* + SignTx signs a transaction using an external wallet. Params: tx (Transaction.Transaction): The transaction to be signed. Returns: - TransactionWitnessSet.TransactionWitnessSet: The withness set associated with the signed transaction. + + + TransactionWitnessSet.TransactionWitnessSet: The withness set associated with the signed transaction. */ -func (ew *ExternalWallet) SignTx(tx Transaction.Transaction) TransactionWitnessSet.TransactionWitnessSet { +func (ew *ExternalWallet) SignTx( + tx Transaction.Transaction, + usedUtxos []UTxO.UTxO, +) TransactionWitnessSet.TransactionWitnessSet { return tx.TransactionWitnessSet } -/** +/* +* + PkeyHash returns the public key hash assoicated with an external wallet. - It computes and returns the public key hash based on the PaymentPart + It computes and returns the public key hash based on the PaymentPart of the wallet's address. Returns: @@ -57,28 +75,56 @@ func (ew *ExternalWallet) PkeyHash() serialization.PubKeyHash { return res } +func (ew *ExternalWallet) SkeyHash() serialization.PubKeyHash { + res := serialization.PubKeyHash(ew.Address.StakingPart) + return res +} + type GenericWallet struct { SigningKey Key.SigningKey VerificationKey Key.VerificationKey Address serAddress.Address - StakeSigningKey Key.StakeSigningKey - StakeVerificationKey Key.StakeVerificationKey + StakeSigningKey Key.SigningKey + StakeVerificationKey Key.VerificationKey } -/** +/* +* + PkeyHash calculates and returns the public key hash associated with a generic wallet. - It computes the public key hash by calling the Hash() method on the wallet's VerificationKey. - Then it returns as a serialization.PubKeyHas type. - - Returns: - serialization.PubKeyHash: The public key hash of the generic wallet. + + + It computes the public key hash by calling the Hash() method on the wallet's VerificationKey. + Then it returns as a serialization.PubKeyHas type. + + Returns: + serialization.PubKeyHash: The public key hash of the generic wallet. */ func (gw *GenericWallet) PkeyHash() serialization.PubKeyHash { res, _ := gw.VerificationKey.Hash() return res } -/** +/* +* + + PkeyHash calculates and returns the stake key hash associated with a generic wallet. + + + It computes the public key hash by calling the Hash() method on the wallet's StakeVerificationKey. + Then it returns as a serialization.PubKeyHash type. + + Returns: + serialization.PubKeyHash: The public stake key hash of the generic wallet. +*/ +func (gw *GenericWallet) SkeyHash() serialization.PubKeyHash { + res, _ := gw.StakeVerificationKey.Hash() + return res +} + +/* +* + GetAddress returns the address associated with a generic wallet. Returns: @@ -88,9 +134,15 @@ func (gw *GenericWallet) GetAddress() *serAddress.Address { return &gw.Address } -/** +/* +* + SignTx signs a transaction using a generic wallet and returns the updated TransactionWitnessSet. + + It takes a transaction of type Transaction.Transaction and signs it using the wallet's SigningKey. + + Then it appends the corresponding VerificationKeyWitness to the TransactionWitnessSet and returns the updated witness set. @@ -99,16 +151,88 @@ func (gw *GenericWallet) GetAddress() *serAddress.Address { tx (Transaction.Transaction): The transaction to be signed. Returns: - TransactionWitnessSet.TransactionWitnessSet: The updated TransactionWitnessSet after signing the transaction. + + + TransactionWitnessSet.TransactionWitnessSet: The updated TransactionWitnessSet after signing the transaction. */ -func (wallet *GenericWallet) SignTx(tx Transaction.Transaction) TransactionWitnessSet.TransactionWitnessSet { +func (wallet *GenericWallet) SignTx( + tx Transaction.Transaction, + usedUtxos []UTxO.UTxO, +) TransactionWitnessSet.TransactionWitnessSet { witness_set := tx.TransactionWitnessSet txHash, _ := tx.TransactionBody.Hash() - signature, _ := wallet.SigningKey.Sign(txHash) - witness_set.VkeyWitnesses = append(witness_set.VkeyWitnesses, VerificationKeyWitness.VerificationKeyWitness{Vkey: wallet.VerificationKey, Signature: signature}) + if isKeyHashUsedFromUtxos(usedUtxos, wallet.PkeyHash()) || + isKeyHashUsedFromTx(tx, wallet.PkeyHash()) { + signature, _ := wallet.SigningKey.Sign(txHash) + + witness_set.VkeyWitnesses = append( + witness_set.VkeyWitnesses, + VerificationKeyWitness.VerificationKeyWitness{ + Vkey: wallet.VerificationKey, + Signature: signature, + }, + ) + } + + if isKeyHashUsedFromUtxos(usedUtxos, wallet.SkeyHash()) || + isKeyHashUsedFromTx(tx, wallet.SkeyHash()) { + signature, _ := wallet.StakeSigningKey.Sign(txHash) + + witness_set.VkeyWitnesses = append( + witness_set.VkeyWitnesses, + VerificationKeyWitness.VerificationKeyWitness{ + Vkey: wallet.StakeVerificationKey, + Signature: signature, + }, + ) + } + return witness_set } +func isKeyHashUsedFromUtxos( + usedUtxos []UTxO.UTxO, + keyHash serialization.PubKeyHash, +) bool { + for _, utxo := range usedUtxos { + utxoKeyHash := serialization.PubKeyHash(utxo.Output.GetAddress().PaymentPart) + if utxoKeyHash == keyHash { + return true + } + } + return false +} + +func isKeyHashUsedFromTx( + tx Transaction.Transaction, + keyHash serialization.PubKeyHash, +) bool { + keyHashBytes := keyHash[:] + for _, certificate := range *tx.TransactionBody.Certificates { + if certificate.StakeCredential.KeyHash() == keyHash { + return true + } + } + for withdrawal := range *tx.TransactionBody.Withdrawals { + withdrawalBytes := withdrawal[1:] + if bytes.Equal(withdrawalBytes, keyHashBytes) { + return true + } + } + for _, requiredSigner := range tx.TransactionBody.RequiredSigners { + if requiredSigner == keyHash { + return true + } + } + for _, nativeScript := range tx.TransactionWitnessSet.NativeScripts { + if bytes.Equal(nativeScript.KeyHash, keyHashBytes) { + return true + } + } + + return false +} + type Backend Base.ChainContext type Address serAddress.Address diff --git a/serialization/Certificate/Certificate.go b/serialization/Certificate/Certificate.go index 1c59ee4..9145c9b 100644 --- a/serialization/Certificate/Certificate.go +++ b/serialization/Certificate/Certificate.go @@ -16,3 +16,16 @@ type Certificate struct { } type Certificates []*Certificate + +func (sc *StakeCredential) Kind() int { + return sc._CODE +} + +func (c *Certificate) Kind() int { + return c._CODE +} + +func (sc *StakeCredential) KeyHash() serialization.PubKeyHash { + res := serialization.PubKeyHash(sc.Credential.Payload) + return res +} diff --git a/serialization/Key/Key.go b/serialization/Key/Key.go index 42804a4..8bd2c2e 100644 --- a/serialization/Key/Key.go +++ b/serialization/Key/Key.go @@ -174,8 +174,6 @@ func PaymentKeyPairGenerate() (*PaymentKeyPair, error) { type PaymentSigningKey SigningKey type PaymentVerificationKey VerificationKey -type StakeSigningKey SigningKey -type StakeVerificationKey VerificationKey /* *