Closed ekko-Huang closed 4 months ago
hey guys. I want to send a registration transaction for a multi-signature wallet, but I don't know how to organize NativeScript and signatures.
import ( "encoding/hex" "fmt" "log" "testing" "github.com/btcsuite/btcutil/bech32" "github.com/echovl/cardano-go" "github.com/echovl/cardano-go/crypto" "github.com/fivebinaries/go-cardano-serialization/address" "github.com/fivebinaries/go-cardano-serialization/bip32" "github.com/fivebinaries/go-cardano-serialization/network" "github.com/tyler-smith/go-bip39" ) func TestMultiSignDelegationTx(t *testing.T) { //m1 := "canyon soft bitter into mixed find cover method junk glide place rabbit" m1 := "where visa pizza bronze tumble indicate loud endorse slice secret hip fix" m2 := "stem mandate sand lecture hip ancient issue happy office about miracle bounce" m3 := "shallow remember arrest magnet resist aspect equip trash season sell bless clown" p1 := getPaymentPrvKey(getRootKey(m1)) payment1 := p1.Public() payment1Hash := payment1.PublicKey().Hash() s1 := getStakePrvKey(getRootKey(m1)) stake1 := s1.Public() stake1Hash := stake1.PublicKey().Hash() p2 := getPaymentPrvKey(getRootKey(m2)) payment2 := p2.Public() payment2Hash := payment2.PublicKey().Hash() s2 := getStakePrvKey(getRootKey(m2)) stake2 := s2.Public() stake2Hash := stake2.PublicKey().Hash() p3 := getPaymentPrvKey(getRootKey(m3)) payment3 := p3.Public() payment3Hash := payment3.PublicKey().Hash() s3 := getStakePrvKey(getRootKey(m3)) stake3 := s3.Public() stake3Hash := stake3.PublicKey().Hash() n := cardano.NativeScript{ Type: ScriptAtLeast, // Require-Of-M N: 2, Scripts: []cardano.NativeScript{ { Type: ScriptPubKey, KeyHash: payment1Hash[:], }, { Type: ScriptPubKey, KeyHash: payment2Hash[:], }, { Type: ScriptPubKey, KeyHash: payment3Hash[:], }, }, } paymentScriptHash, err := n.Hash() if err != nil { panic(err) } s := cardano.NativeScript{ Type: ScriptAtLeast, // Require-Of-M N: 2, Scripts: []cardano.NativeScript{ { Type: ScriptPubKey, KeyHash: stake1Hash[:], }, { Type: ScriptPubKey, KeyHash: stake2Hash[:], }, { Type: ScriptPubKey, KeyHash: stake3Hash[:], }, }, } stakeScriptHash, err := s.Hash() if err != nil { panic(err) } multisign := address.NewBaseAddress( network.TestNet(), &address.StakeCredential{ Kind: address.ScriptStakeCredentialType, Payload: paymentScriptHash, }, &address.StakeCredential{ Kind: address.ScriptStakeCredentialType, Payload: stakeScriptHash, }, ) fmt.Println("multiSign Address:", multisign.String()) fmt.Println("stake Address:", multisign.ToReward().String()) fmt.Println("stakeHash", hex.EncodeToString(stakeScriptHash)) txBuilder := cardano.NewTxBuilder(alonzoProtocol) stakeByte, _ := s.Bytes() stakeByte = append([]byte{byte(0)}, stakeByte...) // create RegistrationCert stakeDelCert, err := cardano.NewStakeRegistrationCertificate(stakeByte) if err != nil { panic(err) } rAddr, _ := cardano.NewAddress(multisign.String()) txInputHash, _ := cardano.NewHash32("e55ae4a146ff4779fc88b772102fae92205b637db41394d53b16d33b658c2c44") txInputAmount := cardano.NewValue(20000000) txBuilder.AddInputs(cardano.NewTxInput(txInputHash, 0, txInputAmount)) txBuilder.AddOutputs(cardano.NewTxOutput(rAddr, cardano.NewValue(17811223))) txBuilder.SetFee(188777) // txBuilder.AddCertificate(stakeDelCert) txBuilder.AddNativeScript(n) txBuilder.AddNativeScript(s) txBuilder.Sign( crypto.PrvKey(p1), crypto.PrvKey(p2), crypto.PrvKey(s1), crypto.PrvKey(s2), ) fmt.Println(hex.EncodeToString(p1.Public().PublicKey()), hex.EncodeToString(p2.Public().PublicKey())) tx, err := txBuilder.Build() if err != nil { panic(err) } fmt.Println(fmt.Sprintf("%+v", tx)) txHash, err := SubmitTx(tx) if err != nil { panic(err) } fmt.Println(txHash) } func getRootKey(mnemonic string) bip32.XPrv { entropy, err := bip39.EntropyFromMnemonic(mnemonic) if err != nil { panic(err) } rootKey := bip32.FromBip39Entropy( entropy, []byte{}, ) return rootKey } func getPaymentPrvKey(rootKey bip32.XPrv) bip32.XPrv { accountKey := rootKey.Derive(harden(1852)).Derive(harden(1815)).Derive(harden(0)) paymentKey := accountKey.Derive(0).Derive(0) return paymentKey } func getStakePrvKey(rootKey bip32.XPrv) bip32.XPrv { accountKey := rootKey.Derive(harden(1852)).Derive(harden(1815)).Derive(harden(0)) stakeKey := accountKey.Derive(2).Derive(0) return stakeKey }
errorMsg :
map[error:Bad Request message:{"contents":{"contents":{"contents":{"era":"ShelleyBasedEraBabbage","error":[{"contents":{"contents":{"contents":{"contents":["74725e00e926bd68e1e787e5f1f57b35c059d95002f8ad33d420050e"],"tag":"ExtraneousScriptWitnessesUTXOW"},"tag":"ShelleyInAlonzoUtxowPredFailure"},"tag":"AlonzoInBabbageUtxowPredFailure"},"tag":"UtxowFailure"}],"kind":"ShelleyTxValidationError"},"tag":"TxValidationErrorInCardanoMode"},"tag":"TxCmdTxSubmitValidationError"},"tag":"TxSubmitFail"} status_code:400]
hey guys. I want to send a registration transaction for a multi-signature wallet, but I don't know how to organize NativeScript and signatures.
errorMsg :