github.com/algorand/go-algorand-sdk@v1.24.0/crypto/crypto_test.go (about) 1 package crypto 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "math/rand" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 "golang.org/x/crypto/ed25519" 11 12 "github.com/algorand/go-algorand-sdk/encoding/msgpack" 13 "github.com/algorand/go-algorand-sdk/mnemonic" 14 "github.com/algorand/go-algorand-sdk/types" 15 ) 16 17 func makeTestMultisigAccount(t *testing.T) (MultisigAccount, ed25519.PrivateKey, ed25519.PrivateKey, ed25519.PrivateKey) { 18 addr1, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA") 19 require.NoError(t, err) 20 addr2, err := types.DecodeAddress("BFRTECKTOOE7A5LHCF3TTEOH2A7BW46IYT2SX5VP6ANKEXHZYJY77SJTVM") 21 require.NoError(t, err) 22 addr3, err := types.DecodeAddress("47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU") 23 require.NoError(t, err) 24 ma, err := MultisigAccountWithParams(1, 2, []types.Address{ 25 addr1, 26 addr2, 27 addr3, 28 }) 29 require.NoError(t, err) 30 mn1 := "auction inquiry lava second expand liberty glass involve ginger illness length room item discover ahead table doctor term tackle cement bonus profit right above catch" 31 sk1, err := mnemonic.ToPrivateKey(mn1) 32 require.NoError(t, err) 33 mn2 := "since during average anxiety protect cherry club long lawsuit loan expand embark forum theory winter park twenty ball kangaroo cram burst board host ability left" 34 sk2, err := mnemonic.ToPrivateKey(mn2) 35 require.NoError(t, err) 36 mn3 := "advice pudding treat near rule blouse same whisper inner electric quit surface sunny dismiss leader blood seat clown cost exist hospital century reform able sponsor" 37 sk3, err := mnemonic.ToPrivateKey(mn3) 38 return ma, sk1, sk2, sk3 39 } 40 41 func TestSignMultisigTransaction(t *testing.T) { 42 ma, sk1, _, _ := makeTestMultisigAccount(t) 43 fromAddr, err := ma.Address() 44 require.NoError(t, err) 45 toAddr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA") 46 require.NoError(t, err) 47 tx := types.Transaction{ 48 Type: types.PaymentTx, 49 Header: types.Header{ 50 Sender: fromAddr, 51 Fee: 217000, 52 FirstValid: 972508, 53 LastValid: 973508, 54 Note: []byte{180, 81, 121, 57, 252, 250, 210, 113}, 55 GenesisID: "testnet-v31.0", 56 }, 57 PaymentTxnFields: types.PaymentTxnFields{ 58 Receiver: toAddr, 59 Amount: 5000, 60 }, 61 } 62 txid, txBytes, err := SignMultisigTransaction(sk1, ma, tx) 63 require.NoError(t, err) 64 expectedBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 118, 246, 119, 203, 209, 172, 34, 112, 79, 186, 215, 112, 41, 206, 201, 203, 230, 167, 215, 112, 156, 141, 37, 117, 149, 203, 209, 1, 132, 10, 96, 236, 87, 193, 248, 19, 228, 31, 230, 43, 94, 17, 231, 187, 158, 96, 148, 216, 202, 128, 206, 243, 48, 88, 234, 68, 38, 5, 169, 86, 146, 111, 121, 0, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 129, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 97, 109, 116, 205, 19, 136, 163, 102, 101, 101, 206, 0, 3, 79, 168, 162, 102, 118, 206, 0, 14, 214, 220, 163, 103, 101, 110, 173, 116, 101, 115, 116, 110, 101, 116, 45, 118, 51, 49, 46, 48, 162, 108, 118, 206, 0, 14, 218, 196, 164, 110, 111, 116, 101, 196, 8, 180, 81, 121, 57, 252, 250, 210, 113, 163, 114, 99, 118, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 163, 112, 97, 121} 65 require.EqualValues(t, expectedBytes, txBytes) 66 expectedTxid := "KY6I7NQXQDAMDUCAVATI45BAODW6NRYQKFH4KIHLH2HQI4DO4XBA" 67 require.Equal(t, expectedTxid, txid) 68 69 // decode and verify 70 var stx types.SignedTxn 71 err = msgpack.Decode(txBytes, &stx) 72 require.NoError(t, err) 73 74 require.Equal(t, types.Address{}, stx.AuthAddr) 75 require.Equal(t, tx, stx.Txn) 76 77 bytesToSign := rawTransactionBytesToSign(stx.Txn) 78 verified := VerifyMultisig(fromAddr, bytesToSign, stx.Msig) 79 require.False(t, verified) // not enough signatures 80 } 81 82 func TestSignMultisigTransactionWithAuthAddr(t *testing.T) { 83 ma, sk1, _, _ := makeTestMultisigAccount(t) 84 multisigAddr, err := ma.Address() 85 require.NoError(t, err) 86 fromAddr, err := types.DecodeAddress("47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU") 87 require.NoError(t, err) 88 toAddr, err := types.DecodeAddress("DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA") 89 require.NoError(t, err) 90 tx := types.Transaction{ 91 Type: types.PaymentTx, 92 Header: types.Header{ 93 Sender: fromAddr, 94 Fee: 217000, 95 FirstValid: 972508, 96 LastValid: 973508, 97 Note: []byte{180, 81, 121, 57, 252, 250, 210, 113}, 98 GenesisID: "testnet-v31.0", 99 }, 100 PaymentTxnFields: types.PaymentTxnFields{ 101 Receiver: toAddr, 102 Amount: 5000, 103 }, 104 } 105 txid, txBytes, err := SignMultisigTransaction(sk1, ma, tx) 106 require.NoError(t, err) 107 expectedBytes := []byte{0x83, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x3e, 0xd3, 0xf2, 0x25, 0x45, 0x61, 0x38, 0x4a, 0x72, 0xca, 0x59, 0x2b, 0xd7, 0xca, 0xfa, 0x7, 0xe, 0x1, 0xb1, 0xce, 0x3c, 0x2e, 0xd8, 0x8c, 0x70, 0x80, 0xa7, 0x9d, 0xe2, 0x88, 0xf7, 0xa2, 0xa3, 0xc9, 0xee, 0x88, 0x0, 0xb, 0x6c, 0x2c, 0x6a, 0x7, 0xca, 0x53, 0x22, 0xcb, 0xc, 0x78, 0x82, 0xcd, 0x42, 0xc9, 0x76, 0x6a, 0x72, 0xed, 0x3f, 0x7c, 0x8a, 0x47, 0x47, 0xaf, 0xb7, 0x0, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 108 require.EqualValues(t, expectedBytes, txBytes) 109 expectedTxid := "HXNXFLSFZQXGOEN33IIQU4OAVZTGXIYHE4HPWFG3RDKKA4OM64JQ" 110 require.Equal(t, expectedTxid, txid) 111 112 // decode and verify 113 var stx types.SignedTxn 114 err = msgpack.Decode(txBytes, &stx) 115 require.NoError(t, err) 116 117 require.Equal(t, multisigAddr, stx.AuthAddr) 118 require.Equal(t, tx, stx.Txn) 119 120 bytesToSign := rawTransactionBytesToSign(stx.Txn) 121 verified := VerifyMultisig(multisigAddr, bytesToSign, stx.Msig) 122 require.False(t, verified) // not enough signatures 123 } 124 125 func TestAppendMultisigTransaction(t *testing.T) { 126 uniSigTxBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 118, 246, 119, 203, 209, 172, 34, 112, 79, 186, 215, 112, 41, 206, 201, 203, 230, 167, 215, 112, 156, 141, 37, 117, 149, 203, 209, 1, 132, 10, 96, 236, 87, 193, 248, 19, 228, 31, 230, 43, 94, 17, 231, 187, 158, 96, 148, 216, 202, 128, 206, 243, 48, 88, 234, 68, 38, 5, 169, 86, 146, 111, 121, 0, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 129, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 97, 109, 116, 205, 19, 136, 163, 102, 101, 101, 206, 0, 3, 79, 168, 162, 102, 118, 206, 0, 14, 214, 220, 163, 103, 101, 110, 173, 116, 101, 115, 116, 110, 101, 116, 45, 118, 51, 49, 46, 48, 162, 108, 118, 206, 0, 14, 218, 196, 164, 110, 111, 116, 101, 196, 8, 180, 81, 121, 57, 252, 250, 210, 113, 163, 114, 99, 118, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 163, 112, 97, 121} 127 ma, _, sk2, _ := makeTestMultisigAccount(t) 128 txid, txBytes, err := AppendMultisigTransaction(sk2, ma, uniSigTxBytes) 129 require.NoError(t, err) 130 expectedBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 118, 246, 119, 203, 209, 172, 34, 112, 79, 186, 215, 112, 41, 206, 201, 203, 230, 167, 215, 112, 156, 141, 37, 117, 149, 203, 209, 1, 132, 10, 96, 236, 87, 193, 248, 19, 228, 31, 230, 43, 94, 17, 231, 187, 158, 96, 148, 216, 202, 128, 206, 243, 48, 88, 234, 68, 38, 5, 169, 86, 146, 111, 121, 0, 130, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 161, 115, 196, 64, 78, 28, 117, 80, 233, 161, 90, 21, 86, 137, 23, 68, 108, 250, 59, 209, 183, 58, 57, 99, 119, 233, 29, 233, 221, 128, 106, 21, 203, 60, 96, 207, 181, 63, 208, 3, 208, 200, 214, 176, 120, 195, 199, 4, 13, 60, 187, 129, 222, 79, 105, 217, 39, 228, 70, 66, 218, 152, 243, 26, 29, 12, 112, 7, 129, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 97, 109, 116, 205, 19, 136, 163, 102, 101, 101, 206, 0, 3, 79, 168, 162, 102, 118, 206, 0, 14, 214, 220, 163, 103, 101, 110, 173, 116, 101, 115, 116, 110, 101, 116, 45, 118, 51, 49, 46, 48, 162, 108, 118, 206, 0, 14, 218, 196, 164, 110, 111, 116, 101, 196, 8, 180, 81, 121, 57, 252, 250, 210, 113, 163, 114, 99, 118, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 163, 112, 97, 121} 131 require.EqualValues(t, expectedBytes, txBytes) 132 expectedTxid := "KY6I7NQXQDAMDUCAVATI45BAODW6NRYQKFH4KIHLH2HQI4DO4XBA" 133 require.Equal(t, expectedTxid, txid) 134 135 // decode and verify 136 var stx types.SignedTxn 137 err = msgpack.Decode(txBytes, &stx) 138 require.NoError(t, err) 139 bytesToSign := rawTransactionBytesToSign(stx.Txn) 140 141 fromAddr, err := ma.Address() 142 require.NoError(t, err) 143 144 require.Equal(t, types.Address{}, stx.AuthAddr) 145 146 verified := VerifyMultisig(fromAddr, bytesToSign, stx.Msig) 147 require.True(t, verified) 148 149 // now change fee and ensure signature verification fails 150 idx := bytes.IndexAny(bytesToSign, "fee") 151 require.NotEqual(t, -1, idx) 152 bytesToSign[idx+4] = 1 153 verified = VerifyMultisig(fromAddr, bytesToSign, stx.Msig) 154 require.False(t, verified) 155 } 156 157 func TestAppendMultisigTransactionWithAuthAddr(t *testing.T) { 158 uniSigTxBytes := []byte{0x83, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x3e, 0xd3, 0xf2, 0x25, 0x45, 0x61, 0x38, 0x4a, 0x72, 0xca, 0x59, 0x2b, 0xd7, 0xca, 0xfa, 0x7, 0xe, 0x1, 0xb1, 0xce, 0x3c, 0x2e, 0xd8, 0x8c, 0x70, 0x80, 0xa7, 0x9d, 0xe2, 0x88, 0xf7, 0xa2, 0xa3, 0xc9, 0xee, 0x88, 0x0, 0xb, 0x6c, 0x2c, 0x6a, 0x7, 0xca, 0x53, 0x22, 0xcb, 0xc, 0x78, 0x82, 0xcd, 0x42, 0xc9, 0x76, 0x6a, 0x72, 0xed, 0x3f, 0x7c, 0x8a, 0x47, 0x47, 0xaf, 0xb7, 0x0, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 159 ma, _, sk2, _ := makeTestMultisigAccount(t) 160 txid, txBytes, err := AppendMultisigTransaction(sk2, ma, uniSigTxBytes) 161 require.NoError(t, err) 162 expectedBytes := []byte{0x83, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x3e, 0xd3, 0xf2, 0x25, 0x45, 0x61, 0x38, 0x4a, 0x72, 0xca, 0x59, 0x2b, 0xd7, 0xca, 0xfa, 0x7, 0xe, 0x1, 0xb1, 0xce, 0x3c, 0x2e, 0xd8, 0x8c, 0x70, 0x80, 0xa7, 0x9d, 0xe2, 0x88, 0xf7, 0xa2, 0xa3, 0xc9, 0xee, 0x88, 0x0, 0xb, 0x6c, 0x2c, 0x6a, 0x7, 0xca, 0x53, 0x22, 0xcb, 0xc, 0x78, 0x82, 0xcd, 0x42, 0xc9, 0x76, 0x6a, 0x72, 0xed, 0x3f, 0x7c, 0x8a, 0x47, 0x47, 0xaf, 0xb7, 0x0, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0xa1, 0x73, 0xc4, 0x40, 0x9c, 0x87, 0x6e, 0x6b, 0x4d, 0xbe, 0x87, 0xba, 0xa2, 0x4e, 0x40, 0x73, 0x73, 0x87, 0xe2, 0xe9, 0x8e, 0x5b, 0x2e, 0x5d, 0x24, 0x93, 0x3c, 0x59, 0x72, 0x31, 0xe0, 0x2f, 0x23, 0x4, 0x6a, 0xa1, 0xd, 0x16, 0x7e, 0x84, 0x32, 0x16, 0x14, 0xe, 0xb2, 0x6f, 0x4, 0x5b, 0xba, 0x9f, 0x39, 0x54, 0x1c, 0x46, 0x58, 0xcc, 0xc4, 0x7e, 0x51, 0x2e, 0xd, 0xee, 0x93, 0xf6, 0xec, 0x66, 0xfa, 0xf, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 163 require.EqualValues(t, expectedBytes, txBytes) 164 expectedTxid := "HXNXFLSFZQXGOEN33IIQU4OAVZTGXIYHE4HPWFG3RDKKA4OM64JQ" 165 require.Equal(t, expectedTxid, txid) 166 167 // decode and verify 168 var stx types.SignedTxn 169 err = msgpack.Decode(txBytes, &stx) 170 require.NoError(t, err) 171 bytesToSign := rawTransactionBytesToSign(stx.Txn) 172 173 multisigAddr, err := ma.Address() 174 require.NoError(t, err) 175 176 require.Equal(t, multisigAddr, stx.AuthAddr) 177 178 verified := VerifyMultisig(multisigAddr, bytesToSign, stx.Msig) 179 require.True(t, verified) 180 181 // now change fee and ensure signature verification fails 182 idx := bytes.IndexAny(bytesToSign, "fee") 183 require.NotEqual(t, -1, idx) 184 bytesToSign[idx+4] = 1 185 verified = VerifyMultisig(multisigAddr, bytesToSign, stx.Msig) 186 require.False(t, verified) 187 } 188 189 func TestSignMultisigTransactionKeyReg(t *testing.T) { 190 rawKeyRegTx := []byte{129, 163, 116, 120, 110, 137, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64} 191 var tx types.SignedTxn 192 err := msgpack.Decode(rawKeyRegTx, &tx) 193 require.NoError(t, err) 194 195 ma, sk1, _, _ := makeTestMultisigAccount(t) 196 txid, txBytes, err := SignMultisigTransaction(sk1, ma, tx.Txn) 197 require.NoError(t, err) 198 expectedBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 186, 52, 94, 163, 20, 123, 21, 228, 212, 78, 168, 14, 159, 234, 210, 219, 69, 206, 23, 113, 13, 3, 226, 107, 74, 6, 121, 202, 250, 195, 62, 13, 205, 64, 12, 208, 205, 69, 221, 116, 29, 15, 86, 243, 209, 159, 143, 116, 161, 84, 144, 104, 113, 8, 99, 78, 68, 12, 149, 213, 4, 83, 201, 15, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 129, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64} 199 require.EqualValues(t, expectedBytes, txBytes) 200 expectedTxid := "2U2QKCYSYA3DUJNVP5T2KWBLWVUMX4PPIGN43IPPVGVZKTNFKJFQ" 201 require.Equal(t, expectedTxid, txid) 202 } 203 204 func TestAppendMultisigTransactionKeyReg(t *testing.T) { 205 uniSigTxBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 186, 52, 94, 163, 20, 123, 21, 228, 212, 78, 168, 14, 159, 234, 210, 219, 69, 206, 23, 113, 13, 3, 226, 107, 74, 6, 121, 202, 250, 195, 62, 13, 205, 64, 12, 208, 205, 69, 221, 116, 29, 15, 86, 243, 209, 159, 143, 116, 161, 84, 144, 104, 113, 8, 99, 78, 68, 12, 149, 213, 4, 83, 201, 15, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 129, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64} 206 ma, _, _, sk3 := makeTestMultisigAccount(t) 207 txid, txBytes, err := AppendMultisigTransaction(sk3, ma, uniSigTxBytes) 208 require.NoError(t, err) 209 expectedBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 186, 52, 94, 163, 20, 123, 21, 228, 212, 78, 168, 14, 159, 234, 210, 219, 69, 206, 23, 113, 13, 3, 226, 107, 74, 6, 121, 202, 250, 195, 62, 13, 205, 64, 12, 208, 205, 69, 221, 116, 29, 15, 86, 243, 209, 159, 143, 116, 161, 84, 144, 104, 113, 8, 99, 78, 68, 12, 149, 213, 4, 83, 201, 15, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 130, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 161, 115, 196, 64, 172, 133, 89, 89, 172, 158, 161, 188, 202, 74, 255, 179, 164, 146, 102, 110, 184, 236, 130, 86, 57, 39, 79, 127, 212, 165, 55, 237, 62, 92, 74, 94, 125, 230, 99, 40, 182, 163, 187, 107, 97, 230, 207, 69, 218, 71, 26, 18, 234, 149, 97, 177, 205, 152, 74, 67, 34, 83, 246, 33, 28, 144, 156, 3, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64} 210 require.EqualValues(t, expectedBytes, txBytes) 211 expectedTxid := "2U2QKCYSYA3DUJNVP5T2KWBLWVUMX4PPIGN43IPPVGVZKTNFKJFQ" 212 require.Equal(t, expectedTxid, txid) 213 } 214 215 func TestMergeMultisigTransactions(t *testing.T) { 216 oneThreeSigTxBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 186, 52, 94, 163, 20, 123, 21, 228, 212, 78, 168, 14, 159, 234, 210, 219, 69, 206, 23, 113, 13, 3, 226, 107, 74, 6, 121, 202, 250, 195, 62, 13, 205, 64, 12, 208, 205, 69, 221, 116, 29, 15, 86, 243, 209, 159, 143, 116, 161, 84, 144, 104, 113, 8, 99, 78, 68, 12, 149, 213, 4, 83, 201, 15, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 130, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 161, 115, 196, 64, 172, 133, 89, 89, 172, 158, 161, 188, 202, 74, 255, 179, 164, 146, 102, 110, 184, 236, 130, 86, 57, 39, 79, 127, 212, 165, 55, 237, 62, 92, 74, 94, 125, 230, 99, 40, 182, 163, 187, 107, 97, 230, 207, 69, 218, 71, 26, 18, 234, 149, 97, 177, 205, 152, 74, 67, 34, 83, 246, 33, 28, 144, 156, 3, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64} 217 twoThreeSigTxBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 129, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 130, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 161, 115, 196, 64, 191, 142, 166, 135, 208, 59, 232, 220, 86, 180, 101, 85, 236, 64, 3, 252, 51, 149, 11, 247, 226, 113, 205, 104, 169, 14, 112, 53, 194, 96, 41, 170, 89, 114, 185, 145, 228, 100, 220, 6, 209, 228, 152, 248, 176, 202, 48, 26, 1, 217, 102, 152, 112, 147, 86, 202, 146, 98, 226, 93, 95, 233, 162, 15, 130, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 161, 115, 196, 64, 172, 133, 89, 89, 172, 158, 161, 188, 202, 74, 255, 179, 164, 146, 102, 110, 184, 236, 130, 86, 57, 39, 79, 127, 212, 165, 55, 237, 62, 92, 74, 94, 125, 230, 99, 40, 182, 163, 187, 107, 97, 230, 207, 69, 218, 71, 26, 18, 234, 149, 97, 177, 205, 152, 74, 67, 34, 83, 246, 33, 28, 144, 156, 3, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64} 218 expectedBytes := []byte{130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 186, 52, 94, 163, 20, 123, 21, 228, 212, 78, 168, 14, 159, 234, 210, 219, 69, 206, 23, 113, 13, 3, 226, 107, 74, 6, 121, 202, 250, 195, 62, 13, 205, 64, 12, 208, 205, 69, 221, 116, 29, 15, 86, 243, 209, 159, 143, 116, 161, 84, 144, 104, 113, 8, 99, 78, 68, 12, 149, 213, 4, 83, 201, 15, 130, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 161, 115, 196, 64, 191, 142, 166, 135, 208, 59, 232, 220, 86, 180, 101, 85, 236, 64, 3, 252, 51, 149, 11, 247, 226, 113, 205, 104, 169, 14, 112, 53, 194, 96, 41, 170, 89, 114, 185, 145, 228, 100, 220, 6, 209, 228, 152, 248, 176, 202, 48, 26, 1, 217, 102, 152, 112, 147, 86, 202, 146, 98, 226, 93, 95, 233, 162, 15, 130, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 161, 115, 196, 64, 172, 133, 89, 89, 172, 158, 161, 188, 202, 74, 255, 179, 164, 146, 102, 110, 184, 236, 130, 86, 57, 39, 79, 127, 212, 165, 55, 237, 62, 92, 74, 94, 125, 230, 99, 40, 182, 163, 187, 107, 97, 230, 207, 69, 218, 71, 26, 18, 234, 149, 97, 177, 205, 152, 74, 67, 34, 83, 246, 33, 28, 144, 156, 3, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 137, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64} 219 _, txBytesSym, err := MergeMultisigTransactions(twoThreeSigTxBytes, oneThreeSigTxBytes) 220 require.NoError(t, err) 221 txid, txBytesSym2, err := MergeMultisigTransactions(oneThreeSigTxBytes, twoThreeSigTxBytes) 222 require.NoError(t, err) 223 224 // make sure merging is symmetric 225 require.EqualValues(t, txBytesSym2, txBytesSym) 226 227 // make sure they match expected output 228 require.EqualValues(t, expectedBytes, txBytesSym) 229 expectedTxid := "2U2QKCYSYA3DUJNVP5T2KWBLWVUMX4PPIGN43IPPVGVZKTNFKJFQ" 230 require.Equal(t, expectedTxid, txid) 231 232 var stx types.SignedTxn 233 err = msgpack.Decode(txBytesSym, &stx) 234 require.NoError(t, err) 235 236 expectedAuthAddr := types.Address{} 237 require.Equal(t, expectedAuthAddr, stx.AuthAddr) 238 } 239 240 func TestMergeMultisigTransactionsWithAuthAddr(t *testing.T) { 241 oneThreeSigTxBytes := []byte{0x83, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x3e, 0xd3, 0xf2, 0x25, 0x45, 0x61, 0x38, 0x4a, 0x72, 0xca, 0x59, 0x2b, 0xd7, 0xca, 0xfa, 0x7, 0xe, 0x1, 0xb1, 0xce, 0x3c, 0x2e, 0xd8, 0x8c, 0x70, 0x80, 0xa7, 0x9d, 0xe2, 0x88, 0xf7, 0xa2, 0xa3, 0xc9, 0xee, 0x88, 0x0, 0xb, 0x6c, 0x2c, 0x6a, 0x7, 0xca, 0x53, 0x22, 0xcb, 0xc, 0x78, 0x82, 0xcd, 0x42, 0xc9, 0x76, 0x6a, 0x72, 0xed, 0x3f, 0x7c, 0x8a, 0x47, 0x47, 0xaf, 0xb7, 0x0, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa1, 0x73, 0xc4, 0x40, 0xb6, 0xf, 0x58, 0x9c, 0xf4, 0xaf, 0xe2, 0xc2, 0xed, 0xf1, 0xba, 0xc5, 0xd6, 0x86, 0x71, 0x18, 0x22, 0xba, 0xf6, 0x6f, 0xbc, 0x84, 0x72, 0x84, 0xb8, 0xce, 0x5a, 0xd8, 0xb1, 0x2c, 0xba, 0x3f, 0xf0, 0x5, 0x20, 0x44, 0xf2, 0x82, 0xff, 0x37, 0x82, 0xfc, 0xb4, 0xf2, 0xd9, 0x53, 0x18, 0xd2, 0xec, 0x5a, 0x9e, 0x5d, 0x0, 0x28, 0x79, 0x41, 0x69, 0xcf, 0xc6, 0x7f, 0x73, 0x99, 0xa0, 0x4, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 242 twoThreeSigTxBytes := []byte{0x83, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0xa1, 0x73, 0xc4, 0x40, 0x9c, 0x87, 0x6e, 0x6b, 0x4d, 0xbe, 0x87, 0xba, 0xa2, 0x4e, 0x40, 0x73, 0x73, 0x87, 0xe2, 0xe9, 0x8e, 0x5b, 0x2e, 0x5d, 0x24, 0x93, 0x3c, 0x59, 0x72, 0x31, 0xe0, 0x2f, 0x23, 0x4, 0x6a, 0xa1, 0xd, 0x16, 0x7e, 0x84, 0x32, 0x16, 0x14, 0xe, 0xb2, 0x6f, 0x4, 0x5b, 0xba, 0x9f, 0x39, 0x54, 0x1c, 0x46, 0x58, 0xcc, 0xc4, 0x7e, 0x51, 0x2e, 0xd, 0xee, 0x93, 0xf6, 0xec, 0x66, 0xfa, 0xf, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa1, 0x73, 0xc4, 0x40, 0xb6, 0xf, 0x58, 0x9c, 0xf4, 0xaf, 0xe2, 0xc2, 0xed, 0xf1, 0xba, 0xc5, 0xd6, 0x86, 0x71, 0x18, 0x22, 0xba, 0xf6, 0x6f, 0xbc, 0x84, 0x72, 0x84, 0xb8, 0xce, 0x5a, 0xd8, 0xb1, 0x2c, 0xba, 0x3f, 0xf0, 0x5, 0x20, 0x44, 0xf2, 0x82, 0xff, 0x37, 0x82, 0xfc, 0xb4, 0xf2, 0xd9, 0x53, 0x18, 0xd2, 0xec, 0x5a, 0x9e, 0x5d, 0x0, 0x28, 0x79, 0x41, 0x69, 0xcf, 0xc6, 0x7f, 0x73, 0x99, 0xa0, 0x4, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 243 expectedBytes := []byte{0x83, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x3e, 0xd3, 0xf2, 0x25, 0x45, 0x61, 0x38, 0x4a, 0x72, 0xca, 0x59, 0x2b, 0xd7, 0xca, 0xfa, 0x7, 0xe, 0x1, 0xb1, 0xce, 0x3c, 0x2e, 0xd8, 0x8c, 0x70, 0x80, 0xa7, 0x9d, 0xe2, 0x88, 0xf7, 0xa2, 0xa3, 0xc9, 0xee, 0x88, 0x0, 0xb, 0x6c, 0x2c, 0x6a, 0x7, 0xca, 0x53, 0x22, 0xcb, 0xc, 0x78, 0x82, 0xcd, 0x42, 0xc9, 0x76, 0x6a, 0x72, 0xed, 0x3f, 0x7c, 0x8a, 0x47, 0x47, 0xaf, 0xb7, 0x0, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0xa1, 0x73, 0xc4, 0x40, 0x9c, 0x87, 0x6e, 0x6b, 0x4d, 0xbe, 0x87, 0xba, 0xa2, 0x4e, 0x40, 0x73, 0x73, 0x87, 0xe2, 0xe9, 0x8e, 0x5b, 0x2e, 0x5d, 0x24, 0x93, 0x3c, 0x59, 0x72, 0x31, 0xe0, 0x2f, 0x23, 0x4, 0x6a, 0xa1, 0xd, 0x16, 0x7e, 0x84, 0x32, 0x16, 0x14, 0xe, 0xb2, 0x6f, 0x4, 0x5b, 0xba, 0x9f, 0x39, 0x54, 0x1c, 0x46, 0x58, 0xcc, 0xc4, 0x7e, 0x51, 0x2e, 0xd, 0xee, 0x93, 0xf6, 0xec, 0x66, 0xfa, 0xf, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa1, 0x73, 0xc4, 0x40, 0xb6, 0xf, 0x58, 0x9c, 0xf4, 0xaf, 0xe2, 0xc2, 0xed, 0xf1, 0xba, 0xc5, 0xd6, 0x86, 0x71, 0x18, 0x22, 0xba, 0xf6, 0x6f, 0xbc, 0x84, 0x72, 0x84, 0xb8, 0xce, 0x5a, 0xd8, 0xb1, 0x2c, 0xba, 0x3f, 0xf0, 0x5, 0x20, 0x44, 0xf2, 0x82, 0xff, 0x37, 0x82, 0xfc, 0xb4, 0xf2, 0xd9, 0x53, 0x18, 0xd2, 0xec, 0x5a, 0x9e, 0x5d, 0x0, 0x28, 0x79, 0x41, 0x69, 0xcf, 0xc6, 0x7f, 0x73, 0x99, 0xa0, 0x4, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 244 245 _, txBytesSym, err := MergeMultisigTransactions(twoThreeSigTxBytes, oneThreeSigTxBytes) 246 require.NoError(t, err) 247 txid, txBytesSym2, err := MergeMultisigTransactions(oneThreeSigTxBytes, twoThreeSigTxBytes) 248 require.NoError(t, err) 249 250 // make sure merging is symmetric 251 require.EqualValues(t, txBytesSym2, txBytesSym) 252 253 // make sure they match expected output 254 require.EqualValues(t, expectedBytes, txBytesSym) 255 expectedTxid := "HXNXFLSFZQXGOEN33IIQU4OAVZTGXIYHE4HPWFG3RDKKA4OM64JQ" 256 require.Equal(t, expectedTxid, txid) 257 258 var stx types.SignedTxn 259 err = msgpack.Decode(txBytesSym, &stx) 260 require.NoError(t, err) 261 262 expectedAuthAddr, err := types.DecodeAddress("RWJLJCMQAFZ2ATP2INM2GZTKNL6OULCCUBO5TQPXH3V2KR4AG7U5UA5JNM") 263 require.NoError(t, err) 264 265 require.Equal(t, expectedAuthAddr, stx.AuthAddr) 266 } 267 268 func TestSignBytes(t *testing.T) { 269 account := GenerateAccount() 270 message := make([]byte, 15) 271 rand.Read(message) 272 signature, err := SignBytes(account.PrivateKey, message) 273 require.NoError(t, err) 274 require.True(t, VerifyBytes(account.PublicKey, message, signature)) 275 if message[0] == 255 { 276 message[0] = 0 277 } else { 278 message[0] = message[0] + 1 279 } 280 require.False(t, VerifyBytes(account.PublicKey, message, signature)) 281 } 282 283 func TestMakeLogicSigBasic(t *testing.T) { 284 // basic checks and contracts without delegation 285 var program []byte 286 var args [][]byte 287 var sk ed25519.PrivateKey 288 var pk MultisigAccount 289 290 // check empty LogicSig 291 lsig, err := MakeLogicSig(program, args, sk, pk) 292 require.Error(t, err) 293 require.Equal(t, types.LogicSig{}, lsig) 294 require.True(t, lsig.Blank()) 295 296 program = []byte{1, 32, 1, 1, 34} 297 programHash := "6Z3C3LDVWGMX23BMSYMANACQOSINPFIRF77H7N3AWJZYV6OH6GWTJKVMXY" 298 contractSender, err := types.DecodeAddress(programHash) 299 require.NoError(t, err) 300 301 lsig, err = MakeLogicSig(program, args, sk, pk) 302 require.NoError(t, err) 303 require.Equal(t, program, lsig.Logic) 304 require.Equal(t, args, lsig.Args) 305 require.Equal(t, types.Signature{}, lsig.Sig) 306 require.True(t, lsig.Msig.Blank()) 307 verified := VerifyLogicSig(lsig, contractSender) 308 require.True(t, verified) 309 require.Equal(t, LogicSigAddress(lsig), contractSender) 310 311 // check arguments 312 args = make([][]byte, 2) 313 args[0] = []byte{1, 2, 3} 314 args[1] = []byte{4, 5, 6} 315 lsig, err = MakeLogicSig(program, args, sk, pk) 316 require.NoError(t, err) 317 require.Equal(t, program, lsig.Logic) 318 require.Equal(t, args, lsig.Args) 319 require.Equal(t, types.Signature{}, lsig.Sig) 320 require.True(t, lsig.Msig.Blank()) 321 verified = VerifyLogicSig(lsig, contractSender) 322 require.True(t, verified) 323 324 // check serialization 325 var lsig1 types.LogicSig 326 encoded := msgpack.Encode(lsig) 327 err = msgpack.Decode(encoded, &lsig1) 328 require.NoError(t, err) 329 require.Equal(t, lsig, lsig1) 330 } 331 332 func TestMakeLogicSigSingle(t *testing.T) { 333 var program []byte 334 var args [][]byte 335 var sk ed25519.PrivateKey 336 var pk MultisigAccount 337 338 acc, err := AccountFromPrivateKey(ed25519.PrivateKey{0xd2, 0xdc, 0x4c, 0xcc, 0xe9, 0x98, 0x62, 0xff, 0xcf, 0x8c, 0xeb, 0x93, 0x6, 0xc4, 0x8d, 0xa6, 0x80, 0x50, 0x82, 0xa, 0xbb, 0x29, 0x95, 0x7a, 0xac, 0x82, 0x68, 0x9a, 0x8c, 0x49, 0x5a, 0x38, 0x5e, 0x67, 0x4f, 0x1c, 0xa, 0xee, 0xec, 0x37, 0x71, 0x89, 0x8f, 0x61, 0xc7, 0x6f, 0xf5, 0xd2, 0x4a, 0x19, 0x79, 0x3e, 0x2c, 0x91, 0xfa, 0x8, 0x51, 0x62, 0x63, 0xe3, 0x85, 0x73, 0xea, 0x42}) 339 require.NoError(t, err) 340 program = []byte{1, 32, 1, 1, 34} 341 sk = acc.PrivateKey 342 lsig, err := MakeLogicSig(program, args, sk, pk) 343 require.NoError(t, err) 344 expectedSig := types.Signature{0x3e, 0x5, 0x3d, 0x39, 0x4d, 0xfb, 0x12, 0xbc, 0x65, 0x79, 0x9f, 0xea, 0x31, 0x8a, 0x7b, 0x8e, 0xa2, 0x51, 0x8b, 0x55, 0x2c, 0x8a, 0xbe, 0x6c, 0xd7, 0xa7, 0x65, 0x2d, 0xd8, 0xb0, 0x18, 0x7e, 0x21, 0x5, 0x2d, 0xb9, 0x24, 0x62, 0x89, 0x16, 0xe5, 0x61, 0x74, 0xcd, 0xf, 0x19, 0xac, 0xb9, 0x6c, 0x45, 0xa4, 0x29, 0x91, 0x99, 0x11, 0x1d, 0xe4, 0x7c, 0xe4, 0xfc, 0x12, 0xec, 0xce, 0x2} 345 require.Equal(t, expectedSig, lsig.Sig) 346 require.True(t, lsig.Msig.Blank()) 347 348 verified := VerifyLogicSig(lsig, acc.Address) 349 require.True(t, verified) 350 351 // check that a modified program fails verification 352 modProgram := make([]byte, len(program)) 353 copy(modProgram, program) 354 lsigModified, err := MakeLogicSig(modProgram, args, sk, pk) 355 require.NoError(t, err) 356 modProgram[3] = 2 357 verified = VerifyLogicSig(lsigModified, acc.Address) 358 require.False(t, verified) 359 360 // check serialization 361 var lsig1 types.LogicSig 362 encoded := msgpack.Encode(lsig) 363 err = msgpack.Decode(encoded, &lsig1) 364 require.NoError(t, err) 365 require.Equal(t, lsig, lsig1) 366 } 367 368 func TestMakeLogicSigMulti(t *testing.T) { 369 var program []byte 370 var args [][]byte 371 var sk ed25519.PrivateKey 372 var pk MultisigAccount 373 374 ma, sk1, sk2, _ := makeTestMultisigAccount(t) 375 program = []byte{1, 32, 1, 1, 34} 376 sender, err := ma.Address() 377 require.NoError(t, err) 378 acc := GenerateAccount() 379 sk = acc.PrivateKey 380 381 lsig, err := MakeLogicSig(program, args, sk1, ma) 382 require.NoError(t, err) 383 require.Equal(t, program, lsig.Logic) 384 require.Equal(t, args, lsig.Args) 385 require.Equal(t, types.Signature{}, lsig.Sig) 386 require.False(t, lsig.Msig.Blank()) 387 388 verified := VerifyLogicSig(lsig, sender) 389 require.False(t, verified) // not enough signatures 390 391 err = AppendMultisigToLogicSig(&lsig, sk) 392 require.Error(t, err) // sk not part of multisig 393 394 err = AppendMultisigToLogicSig(&lsig, sk2) 395 require.NoError(t, err) 396 397 verified = VerifyLogicSig(lsig, sender) 398 require.True(t, verified) 399 400 // check that a modified program fails verification 401 modProgram := make([]byte, len(program)) 402 copy(modProgram, program) 403 lsigModified, err := MakeLogicSig(modProgram, args, sk1, ma) 404 require.NoError(t, err) 405 modProgram[3] = 2 406 verified = VerifyLogicSig(lsigModified, sender) 407 require.False(t, verified) 408 409 // combine sig and multisig, ensure it fails 410 lsigf, err := MakeLogicSig(program, args, sk, pk) 411 require.NoError(t, err) 412 lsig.Sig = lsigf.Sig 413 414 verified = VerifyLogicSig(lsig, sender) 415 require.False(t, verified) // sig + msig 416 417 // remove sig and ensure things are good 418 lsig.Sig = types.Signature{} 419 verified = VerifyLogicSig(lsig, sender) 420 require.True(t, verified) 421 422 // check serialization 423 var lsig1 types.LogicSig 424 encoded := msgpack.Encode(lsig) 425 err = msgpack.Decode(encoded, &lsig1) 426 require.NoError(t, err) 427 require.Equal(t, lsig, lsig1) 428 } 429 430 func TestSignLogicsigTransaction(t *testing.T) { 431 program := []byte{1, 32, 1, 1, 34} 432 args := [][]byte{ 433 {0x01}, 434 {0x02, 0x03}, 435 } 436 437 otherAddrStr := "WTDCE2FEYM2VB5MKNXKLRSRDTSPR2EFTIGVH4GRW4PHGD6747GFJTBGT2A" 438 otherAddr, err := types.DecodeAddress(otherAddrStr) 439 require.NoError(t, err) 440 441 testSign := func(t *testing.T, lsig types.LogicSig, sender types.Address, expectedBytes []byte, expectedTxid string, expectedAuthAddr types.Address) { 442 txn := types.Transaction{ 443 Type: types.PaymentTx, 444 Header: types.Header{ 445 Sender: sender, 446 Fee: 217000, 447 FirstValid: 972508, 448 LastValid: 973508, 449 Note: []byte{180, 81, 121, 57, 252, 250, 210, 113}, 450 GenesisID: "testnet-v31.0", 451 }, 452 PaymentTxnFields: types.PaymentTxnFields{ 453 Receiver: otherAddr, 454 Amount: 5000, 455 }, 456 } 457 458 txid, stxnBytes, err := SignLogicsigTransaction(lsig, txn) 459 require.NoError(t, err) 460 require.EqualValues(t, expectedBytes, stxnBytes) 461 require.Equal(t, expectedTxid, txid) 462 463 // decode and verify 464 var stx types.SignedTxn 465 err = msgpack.Decode(stxnBytes, &stx) 466 require.NoError(t, err) 467 468 require.Equal(t, expectedAuthAddr, stx.AuthAddr) 469 470 require.Equal(t, lsig, stx.Lsig) 471 require.Equal(t, types.Signature{}, stx.Sig) 472 require.True(t, stx.Msig.Blank()) 473 474 require.Equal(t, txn, stx.Txn) 475 } 476 477 t.Run("no sig", func(t *testing.T) { 478 var sk ed25519.PrivateKey 479 var ma MultisigAccount 480 lsig, err := MakeLogicSig(program, args, sk, ma) 481 require.NoError(t, err) 482 483 programHash := "6Z3C3LDVWGMX23BMSYMANACQOSINPFIRF77H7N3AWJZYV6OH6GWTJKVMXY" 484 programAddr, err := types.DecodeAddress(programHash) 485 require.NoError(t, err) 486 487 t.Run("sender is contract addr", func(t *testing.T) { 488 expectedBytes := []byte{0x82, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x82, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xf6, 0x76, 0x2d, 0xac, 0x75, 0xb1, 0x99, 0x7d, 0x6c, 0x2c, 0x96, 0x18, 0x6, 0x80, 0x50, 0x74, 0x90, 0xd7, 0x95, 0x11, 0x2f, 0xfe, 0x7f, 0xb7, 0x60, 0xb2, 0x73, 0x8a, 0xf9, 0xc7, 0xf1, 0xad, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 489 expectedTxid := "IL5UCKXGWBA2MQ4YYFQKYC3BFCWO2KHZSNZWVDIXOOZS3AWVIQDA" 490 expectedAuthAddr := types.Address{} 491 sender := programAddr 492 testSign(t, lsig, sender, expectedBytes, expectedTxid, expectedAuthAddr) 493 }) 494 495 t.Run("sender is not contract addr", func(t *testing.T) { 496 expectedBytes := []byte{0x83, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x82, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0xf6, 0x76, 0x2d, 0xac, 0x75, 0xb1, 0x99, 0x7d, 0x6c, 0x2c, 0x96, 0x18, 0x6, 0x80, 0x50, 0x74, 0x90, 0xd7, 0x95, 0x11, 0x2f, 0xfe, 0x7f, 0xb7, 0x60, 0xb2, 0x73, 0x8a, 0xf9, 0xc7, 0xf1, 0xad, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 497 expectedTxid := "U4X24Q45MCZ6JSL343QNR3RC6AJO2NUDQXFCTNONIW3SU2AYQJOA" 498 expectedAuthAddr := programAddr 499 sender := otherAddr 500 testSign(t, lsig, sender, expectedBytes, expectedTxid, expectedAuthAddr) 501 }) 502 }) 503 504 t.Run("single sig", func(t *testing.T) { 505 var ma MultisigAccount 506 acc, err := AccountFromPrivateKey(ed25519.PrivateKey{0xd2, 0xdc, 0x4c, 0xcc, 0xe9, 0x98, 0x62, 0xff, 0xcf, 0x8c, 0xeb, 0x93, 0x6, 0xc4, 0x8d, 0xa6, 0x80, 0x50, 0x82, 0xa, 0xbb, 0x29, 0x95, 0x7a, 0xac, 0x82, 0x68, 0x9a, 0x8c, 0x49, 0x5a, 0x38, 0x5e, 0x67, 0x4f, 0x1c, 0xa, 0xee, 0xec, 0x37, 0x71, 0x89, 0x8f, 0x61, 0xc7, 0x6f, 0xf5, 0xd2, 0x4a, 0x19, 0x79, 0x3e, 0x2c, 0x91, 0xfa, 0x8, 0x51, 0x62, 0x63, 0xe3, 0x85, 0x73, 0xea, 0x42}) 507 require.NoError(t, err) 508 lsig, err := MakeLogicSig(program, args, acc.PrivateKey, ma) 509 require.NoError(t, err) 510 511 t.Run("sender is contract addr", func(t *testing.T) { 512 expectedBytes := []byte{0x82, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x83, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa3, 0x73, 0x69, 0x67, 0xc4, 0x40, 0x3e, 0x5, 0x3d, 0x39, 0x4d, 0xfb, 0x12, 0xbc, 0x65, 0x79, 0x9f, 0xea, 0x31, 0x8a, 0x7b, 0x8e, 0xa2, 0x51, 0x8b, 0x55, 0x2c, 0x8a, 0xbe, 0x6c, 0xd7, 0xa7, 0x65, 0x2d, 0xd8, 0xb0, 0x18, 0x7e, 0x21, 0x5, 0x2d, 0xb9, 0x24, 0x62, 0x89, 0x16, 0xe5, 0x61, 0x74, 0xcd, 0xf, 0x19, 0xac, 0xb9, 0x6c, 0x45, 0xa4, 0x29, 0x91, 0x99, 0x11, 0x1d, 0xe4, 0x7c, 0xe4, 0xfc, 0x12, 0xec, 0xce, 0x2, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0x5e, 0x67, 0x4f, 0x1c, 0xa, 0xee, 0xec, 0x37, 0x71, 0x89, 0x8f, 0x61, 0xc7, 0x6f, 0xf5, 0xd2, 0x4a, 0x19, 0x79, 0x3e, 0x2c, 0x91, 0xfa, 0x8, 0x51, 0x62, 0x63, 0xe3, 0x85, 0x73, 0xea, 0x42, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 513 expectedTxid := "XPFTYDOV5RCL7K5EGTC32PSTRKFO3ITZIL64CRTYIJEPHXOTCCXA" 514 expectedAuthAddr := types.Address{} 515 sender := acc.Address 516 testSign(t, lsig, sender, expectedBytes, expectedTxid, expectedAuthAddr) 517 }) 518 519 t.Run("sender is not contract addr", func(t *testing.T) { 520 txn := types.Transaction{ 521 Type: types.PaymentTx, 522 Header: types.Header{ 523 Sender: otherAddr, 524 Fee: 217000, 525 FirstValid: 972508, 526 LastValid: 973508, 527 Note: []byte{180, 81, 121, 57, 252, 250, 210, 113}, 528 GenesisID: "testnet-v31.0", 529 }, 530 PaymentTxnFields: types.PaymentTxnFields{ 531 Receiver: otherAddr, 532 Amount: 5000, 533 }, 534 } 535 536 _, _, err := SignLogicsigTransaction(lsig, txn) 537 require.Error(t, err, errLsigInvalidSignature) 538 }) 539 }) 540 541 t.Run("multi sig", func(t *testing.T) { 542 ma, sk1, sk2, _ := makeTestMultisigAccount(t) 543 maAddr, err := ma.Address() 544 require.NoError(t, err) 545 546 lsig, err := MakeLogicSig(program, args, sk1, ma) 547 require.NoError(t, err) 548 549 err = AppendMultisigToLogicSig(&lsig, sk2) 550 require.NoError(t, err) 551 552 t.Run("sender is contract addr", func(t *testing.T) { 553 expectedBytes := []byte{0x82, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x83, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x49, 0x13, 0xb8, 0x5, 0xd1, 0x9e, 0x7f, 0x2c, 0x10, 0x80, 0xf6, 0x33, 0x7e, 0x18, 0x54, 0xa7, 0xce, 0xea, 0xee, 0x10, 0xdd, 0xbd, 0x13, 0x65, 0x84, 0xbf, 0x93, 0xb7, 0x5f, 0x30, 0x63, 0x15, 0x91, 0xca, 0x23, 0xc, 0xed, 0xef, 0x23, 0xd1, 0x74, 0x1b, 0x52, 0x9d, 0xb0, 0xff, 0xef, 0x37, 0x54, 0xd6, 0x46, 0xf4, 0xb5, 0x61, 0xfc, 0x8b, 0xbc, 0x2d, 0x7b, 0x4e, 0x63, 0x5c, 0xbd, 0x2, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0xa1, 0x73, 0xc4, 0x40, 0x64, 0xbc, 0x55, 0xdb, 0xed, 0x91, 0xa2, 0x41, 0xd4, 0x2a, 0xb6, 0x60, 0xf7, 0xe1, 0x4a, 0xb9, 0x99, 0x9a, 0x52, 0xb3, 0xb1, 0x71, 0x58, 0xce, 0xfc, 0x3f, 0x4f, 0xe7, 0xcb, 0x22, 0x41, 0x14, 0xad, 0xa9, 0x3d, 0x5e, 0x84, 0x5, 0x2, 0xa, 0x17, 0xa6, 0x69, 0x83, 0x3, 0x22, 0x4e, 0x86, 0xa3, 0x8b, 0x6a, 0x36, 0xc5, 0x54, 0xbe, 0x20, 0x50, 0xff, 0xd3, 0xee, 0xa8, 0xb3, 0x4, 0x9, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 554 expectedTxid := "2I2QT3MGXNMB5IOTNWEQZWUJCHLJ5QFBYI264X5NWMUDKZXPZ5RA" 555 expectedAuthAddr := types.Address{} 556 sender := maAddr 557 testSign(t, lsig, sender, expectedBytes, expectedTxid, expectedAuthAddr) 558 }) 559 560 t.Run("sender is not contract addr", func(t *testing.T) { 561 expectedBytes := []byte{0x83, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x83, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x49, 0x13, 0xb8, 0x5, 0xd1, 0x9e, 0x7f, 0x2c, 0x10, 0x80, 0xf6, 0x33, 0x7e, 0x18, 0x54, 0xa7, 0xce, 0xea, 0xee, 0x10, 0xdd, 0xbd, 0x13, 0x65, 0x84, 0xbf, 0x93, 0xb7, 0x5f, 0x30, 0x63, 0x15, 0x91, 0xca, 0x23, 0xc, 0xed, 0xef, 0x23, 0xd1, 0x74, 0x1b, 0x52, 0x9d, 0xb0, 0xff, 0xef, 0x37, 0x54, 0xd6, 0x46, 0xf4, 0xb5, 0x61, 0xfc, 0x8b, 0xbc, 0x2d, 0x7b, 0x4e, 0x63, 0x5c, 0xbd, 0x2, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0xa1, 0x73, 0xc4, 0x40, 0x64, 0xbc, 0x55, 0xdb, 0xed, 0x91, 0xa2, 0x41, 0xd4, 0x2a, 0xb6, 0x60, 0xf7, 0xe1, 0x4a, 0xb9, 0x99, 0x9a, 0x52, 0xb3, 0xb1, 0x71, 0x58, 0xce, 0xfc, 0x3f, 0x4f, 0xe7, 0xcb, 0x22, 0x41, 0x14, 0xad, 0xa9, 0x3d, 0x5e, 0x84, 0x5, 0x2, 0xa, 0x17, 0xa6, 0x69, 0x83, 0x3, 0x22, 0x4e, 0x86, 0xa3, 0x8b, 0x6a, 0x36, 0xc5, 0x54, 0xbe, 0x20, 0x50, 0xff, 0xd3, 0xee, 0xa8, 0xb3, 0x4, 0x9, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 562 expectedTxid := "U4X24Q45MCZ6JSL343QNR3RC6AJO2NUDQXFCTNONIW3SU2AYQJOA" 563 expectedAuthAddr := maAddr 564 sender := otherAddr 565 testSign(t, lsig, sender, expectedBytes, expectedTxid, expectedAuthAddr) 566 }) 567 }) 568 } 569 570 func TestSignLogicSigAccountTransaction(t *testing.T) { 571 program := []byte{1, 32, 1, 1, 34} 572 args := [][]byte{ 573 {0x01}, 574 {0x02, 0x03}, 575 } 576 577 otherAddrStr := "WTDCE2FEYM2VB5MKNXKLRSRDTSPR2EFTIGVH4GRW4PHGD6747GFJTBGT2A" 578 otherAddr, err := types.DecodeAddress(otherAddrStr) 579 require.NoError(t, err) 580 581 testSign := func(t *testing.T, lsa LogicSigAccount, sender types.Address, expectedBytes []byte, expectedTxid string, expectedAuthAddr types.Address) { 582 txn := types.Transaction{ 583 Type: types.PaymentTx, 584 Header: types.Header{ 585 Sender: sender, 586 Fee: 217000, 587 FirstValid: 972508, 588 LastValid: 973508, 589 Note: []byte{180, 81, 121, 57, 252, 250, 210, 113}, 590 GenesisID: "testnet-v31.0", 591 }, 592 PaymentTxnFields: types.PaymentTxnFields{ 593 Receiver: otherAddr, 594 Amount: 5000, 595 }, 596 } 597 598 txid, stxnBytes, err := SignLogicSigAccountTransaction(lsa, txn) 599 require.NoError(t, err) 600 require.EqualValues(t, expectedBytes, stxnBytes) 601 require.Equal(t, expectedTxid, txid) 602 603 // decode and verify 604 var stx types.SignedTxn 605 err = msgpack.Decode(stxnBytes, &stx) 606 require.NoError(t, err) 607 608 require.Equal(t, expectedAuthAddr, stx.AuthAddr) 609 610 require.Equal(t, lsa.Lsig, stx.Lsig) 611 require.Equal(t, types.Signature{}, stx.Sig) 612 require.True(t, stx.Msig.Blank()) 613 614 require.Equal(t, types.Signature{}, stx.Sig) 615 require.True(t, stx.Msig.Blank()) 616 617 require.Equal(t, txn, stx.Txn) 618 } 619 620 t.Run("no sig", func(t *testing.T) { 621 lsigAccount := MakeLogicSigAccountEscrow(program, args) 622 623 programAddr, err := types.DecodeAddress("6Z3C3LDVWGMX23BMSYMANACQOSINPFIRF77H7N3AWJZYV6OH6GWTJKVMXY") 624 require.NoError(t, err) 625 626 t.Run("sender is contract addr", func(t *testing.T) { 627 expectedBytes := []byte{0x82, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x82, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xf6, 0x76, 0x2d, 0xac, 0x75, 0xb1, 0x99, 0x7d, 0x6c, 0x2c, 0x96, 0x18, 0x6, 0x80, 0x50, 0x74, 0x90, 0xd7, 0x95, 0x11, 0x2f, 0xfe, 0x7f, 0xb7, 0x60, 0xb2, 0x73, 0x8a, 0xf9, 0xc7, 0xf1, 0xad, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 628 expectedTxid := "IL5UCKXGWBA2MQ4YYFQKYC3BFCWO2KHZSNZWVDIXOOZS3AWVIQDA" 629 expectedAuthAddr := types.Address{} 630 sender := programAddr 631 testSign(t, lsigAccount, sender, expectedBytes, expectedTxid, expectedAuthAddr) 632 }) 633 634 t.Run("sender is not contract addr", func(t *testing.T) { 635 expectedBytes := []byte{0x83, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x82, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0xf6, 0x76, 0x2d, 0xac, 0x75, 0xb1, 0x99, 0x7d, 0x6c, 0x2c, 0x96, 0x18, 0x6, 0x80, 0x50, 0x74, 0x90, 0xd7, 0x95, 0x11, 0x2f, 0xfe, 0x7f, 0xb7, 0x60, 0xb2, 0x73, 0x8a, 0xf9, 0xc7, 0xf1, 0xad, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 636 expectedTxid := "U4X24Q45MCZ6JSL343QNR3RC6AJO2NUDQXFCTNONIW3SU2AYQJOA" 637 expectedAuthAddr := programAddr 638 sender := otherAddr 639 testSign(t, lsigAccount, sender, expectedBytes, expectedTxid, expectedAuthAddr) 640 }) 641 }) 642 643 t.Run("single sig", func(t *testing.T) { 644 account, err := AccountFromPrivateKey(ed25519.PrivateKey{0xd2, 0xdc, 0x4c, 0xcc, 0xe9, 0x98, 0x62, 0xff, 0xcf, 0x8c, 0xeb, 0x93, 0x6, 0xc4, 0x8d, 0xa6, 0x80, 0x50, 0x82, 0xa, 0xbb, 0x29, 0x95, 0x7a, 0xac, 0x82, 0x68, 0x9a, 0x8c, 0x49, 0x5a, 0x38, 0x5e, 0x67, 0x4f, 0x1c, 0xa, 0xee, 0xec, 0x37, 0x71, 0x89, 0x8f, 0x61, 0xc7, 0x6f, 0xf5, 0xd2, 0x4a, 0x19, 0x79, 0x3e, 0x2c, 0x91, 0xfa, 0x8, 0x51, 0x62, 0x63, 0xe3, 0x85, 0x73, 0xea, 0x42}) 645 require.NoError(t, err) 646 647 lsigAccount, err := MakeLogicSigAccountDelegated(program, args, account.PrivateKey) 648 require.NoError(t, err) 649 650 t.Run("sender is contract addr", func(t *testing.T) { 651 expectedBytes := []byte{0x82, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x83, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa3, 0x73, 0x69, 0x67, 0xc4, 0x40, 0x3e, 0x5, 0x3d, 0x39, 0x4d, 0xfb, 0x12, 0xbc, 0x65, 0x79, 0x9f, 0xea, 0x31, 0x8a, 0x7b, 0x8e, 0xa2, 0x51, 0x8b, 0x55, 0x2c, 0x8a, 0xbe, 0x6c, 0xd7, 0xa7, 0x65, 0x2d, 0xd8, 0xb0, 0x18, 0x7e, 0x21, 0x5, 0x2d, 0xb9, 0x24, 0x62, 0x89, 0x16, 0xe5, 0x61, 0x74, 0xcd, 0xf, 0x19, 0xac, 0xb9, 0x6c, 0x45, 0xa4, 0x29, 0x91, 0x99, 0x11, 0x1d, 0xe4, 0x7c, 0xe4, 0xfc, 0x12, 0xec, 0xce, 0x2, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0x5e, 0x67, 0x4f, 0x1c, 0xa, 0xee, 0xec, 0x37, 0x71, 0x89, 0x8f, 0x61, 0xc7, 0x6f, 0xf5, 0xd2, 0x4a, 0x19, 0x79, 0x3e, 0x2c, 0x91, 0xfa, 0x8, 0x51, 0x62, 0x63, 0xe3, 0x85, 0x73, 0xea, 0x42, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 652 expectedTxid := "XPFTYDOV5RCL7K5EGTC32PSTRKFO3ITZIL64CRTYIJEPHXOTCCXA" 653 expectedAuthAddr := types.Address{} 654 sender := account.Address 655 testSign(t, lsigAccount, sender, expectedBytes, expectedTxid, expectedAuthAddr) 656 }) 657 658 t.Run("sender is not contract addr", func(t *testing.T) { 659 expectedBytes := []byte{0x83, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x83, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa3, 0x73, 0x69, 0x67, 0xc4, 0x40, 0x3e, 0x5, 0x3d, 0x39, 0x4d, 0xfb, 0x12, 0xbc, 0x65, 0x79, 0x9f, 0xea, 0x31, 0x8a, 0x7b, 0x8e, 0xa2, 0x51, 0x8b, 0x55, 0x2c, 0x8a, 0xbe, 0x6c, 0xd7, 0xa7, 0x65, 0x2d, 0xd8, 0xb0, 0x18, 0x7e, 0x21, 0x5, 0x2d, 0xb9, 0x24, 0x62, 0x89, 0x16, 0xe5, 0x61, 0x74, 0xcd, 0xf, 0x19, 0xac, 0xb9, 0x6c, 0x45, 0xa4, 0x29, 0x91, 0x99, 0x11, 0x1d, 0xe4, 0x7c, 0xe4, 0xfc, 0x12, 0xec, 0xce, 0x2, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x5e, 0x67, 0x4f, 0x1c, 0xa, 0xee, 0xec, 0x37, 0x71, 0x89, 0x8f, 0x61, 0xc7, 0x6f, 0xf5, 0xd2, 0x4a, 0x19, 0x79, 0x3e, 0x2c, 0x91, 0xfa, 0x8, 0x51, 0x62, 0x63, 0xe3, 0x85, 0x73, 0xea, 0x42, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 660 expectedTxid := "U4X24Q45MCZ6JSL343QNR3RC6AJO2NUDQXFCTNONIW3SU2AYQJOA" 661 expectedAuthAddr := account.Address 662 sender := otherAddr 663 testSign(t, lsigAccount, sender, expectedBytes, expectedTxid, expectedAuthAddr) 664 }) 665 }) 666 667 t.Run("multi sig", func(t *testing.T) { 668 ma, sk1, sk2, _ := makeTestMultisigAccount(t) 669 maAddr, err := ma.Address() 670 require.NoError(t, err) 671 672 lsigAccount, err := MakeLogicSigAccountDelegatedMsig(program, args, ma, sk1) 673 require.NoError(t, err) 674 675 err = lsigAccount.AppendMultisigSignature(sk2) 676 require.NoError(t, err) 677 678 t.Run("sender is contract addr", func(t *testing.T) { 679 expectedBytes := []byte{0x82, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x83, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x49, 0x13, 0xb8, 0x5, 0xd1, 0x9e, 0x7f, 0x2c, 0x10, 0x80, 0xf6, 0x33, 0x7e, 0x18, 0x54, 0xa7, 0xce, 0xea, 0xee, 0x10, 0xdd, 0xbd, 0x13, 0x65, 0x84, 0xbf, 0x93, 0xb7, 0x5f, 0x30, 0x63, 0x15, 0x91, 0xca, 0x23, 0xc, 0xed, 0xef, 0x23, 0xd1, 0x74, 0x1b, 0x52, 0x9d, 0xb0, 0xff, 0xef, 0x37, 0x54, 0xd6, 0x46, 0xf4, 0xb5, 0x61, 0xfc, 0x8b, 0xbc, 0x2d, 0x7b, 0x4e, 0x63, 0x5c, 0xbd, 0x2, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0xa1, 0x73, 0xc4, 0x40, 0x64, 0xbc, 0x55, 0xdb, 0xed, 0x91, 0xa2, 0x41, 0xd4, 0x2a, 0xb6, 0x60, 0xf7, 0xe1, 0x4a, 0xb9, 0x99, 0x9a, 0x52, 0xb3, 0xb1, 0x71, 0x58, 0xce, 0xfc, 0x3f, 0x4f, 0xe7, 0xcb, 0x22, 0x41, 0x14, 0xad, 0xa9, 0x3d, 0x5e, 0x84, 0x5, 0x2, 0xa, 0x17, 0xa6, 0x69, 0x83, 0x3, 0x22, 0x4e, 0x86, 0xa3, 0x8b, 0x6a, 0x36, 0xc5, 0x54, 0xbe, 0x20, 0x50, 0xff, 0xd3, 0xee, 0xa8, 0xb3, 0x4, 0x9, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 680 expectedTxid := "2I2QT3MGXNMB5IOTNWEQZWUJCHLJ5QFBYI264X5NWMUDKZXPZ5RA" 681 expectedAuthAddr := types.Address{} 682 sender := maAddr 683 testSign(t, lsigAccount, sender, expectedBytes, expectedTxid, expectedAuthAddr) 684 }) 685 686 t.Run("sender is not contract addr", func(t *testing.T) { 687 expectedBytes := []byte{0x83, 0xa4, 0x6c, 0x73, 0x69, 0x67, 0x83, 0xa3, 0x61, 0x72, 0x67, 0x92, 0xc4, 0x1, 0x1, 0xc4, 0x2, 0x2, 0x3, 0xa1, 0x6c, 0xc4, 0x5, 0x1, 0x20, 0x1, 0x1, 0x22, 0xa4, 0x6d, 0x73, 0x69, 0x67, 0x83, 0xa6, 0x73, 0x75, 0x62, 0x73, 0x69, 0x67, 0x93, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x1b, 0x7e, 0xc0, 0xb0, 0x4b, 0xea, 0x61, 0xb7, 0x96, 0x90, 0x97, 0xe6, 0xcb, 0xf4, 0x7, 0xe1, 0x8, 0xa7, 0x5, 0x35, 0x1d, 0xb, 0xc9, 0x8a, 0xbe, 0xb1, 0x22, 0x9, 0xa8, 0xab, 0x81, 0x78, 0xa1, 0x73, 0xc4, 0x40, 0x49, 0x13, 0xb8, 0x5, 0xd1, 0x9e, 0x7f, 0x2c, 0x10, 0x80, 0xf6, 0x33, 0x7e, 0x18, 0x54, 0xa7, 0xce, 0xea, 0xee, 0x10, 0xdd, 0xbd, 0x13, 0x65, 0x84, 0xbf, 0x93, 0xb7, 0x5f, 0x30, 0x63, 0x15, 0x91, 0xca, 0x23, 0xc, 0xed, 0xef, 0x23, 0xd1, 0x74, 0x1b, 0x52, 0x9d, 0xb0, 0xff, 0xef, 0x37, 0x54, 0xd6, 0x46, 0xf4, 0xb5, 0x61, 0xfc, 0x8b, 0xbc, 0x2d, 0x7b, 0x4e, 0x63, 0x5c, 0xbd, 0x2, 0x82, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0x9, 0x63, 0x32, 0x9, 0x53, 0x73, 0x89, 0xf0, 0x75, 0x67, 0x11, 0x77, 0x39, 0x91, 0xc7, 0xd0, 0x3e, 0x1b, 0x73, 0xc8, 0xc4, 0xf5, 0x2b, 0xf6, 0xaf, 0xf0, 0x1a, 0xa2, 0x5c, 0xf9, 0xc2, 0x71, 0xa1, 0x73, 0xc4, 0x40, 0x64, 0xbc, 0x55, 0xdb, 0xed, 0x91, 0xa2, 0x41, 0xd4, 0x2a, 0xb6, 0x60, 0xf7, 0xe1, 0x4a, 0xb9, 0x99, 0x9a, 0x52, 0xb3, 0xb1, 0x71, 0x58, 0xce, 0xfc, 0x3f, 0x4f, 0xe7, 0xcb, 0x22, 0x41, 0x14, 0xad, 0xa9, 0x3d, 0x5e, 0x84, 0x5, 0x2, 0xa, 0x17, 0xa6, 0x69, 0x83, 0x3, 0x22, 0x4e, 0x86, 0xa3, 0x8b, 0x6a, 0x36, 0xc5, 0x54, 0xbe, 0x20, 0x50, 0xff, 0xd3, 0xee, 0xa8, 0xb3, 0x4, 0x9, 0x81, 0xa2, 0x70, 0x6b, 0xc4, 0x20, 0xe7, 0xf0, 0xf8, 0x4d, 0x6, 0x81, 0x1d, 0xf9, 0xf3, 0x1c, 0x8d, 0x87, 0x8b, 0x11, 0x55, 0xf4, 0x67, 0x1d, 0x51, 0xa1, 0x85, 0xc2, 0x0, 0x90, 0x86, 0x67, 0xf4, 0x49, 0x58, 0x70, 0x68, 0xa1, 0xa3, 0x74, 0x68, 0x72, 0x2, 0xa1, 0x76, 0x1, 0xa4, 0x73, 0x67, 0x6e, 0x72, 0xc4, 0x20, 0x8d, 0x92, 0xb4, 0x89, 0x90, 0x1, 0x73, 0xa0, 0x4d, 0xfa, 0x43, 0x59, 0xa3, 0x66, 0x6a, 0x6a, 0xfc, 0xea, 0x2c, 0x42, 0xa0, 0x5d, 0xd9, 0xc1, 0xf7, 0x3e, 0xeb, 0xa5, 0x47, 0x80, 0x37, 0xe9, 0xa3, 0x74, 0x78, 0x6e, 0x89, 0xa3, 0x61, 0x6d, 0x74, 0xcd, 0x13, 0x88, 0xa3, 0x66, 0x65, 0x65, 0xce, 0x0, 0x3, 0x4f, 0xa8, 0xa2, 0x66, 0x76, 0xce, 0x0, 0xe, 0xd6, 0xdc, 0xa3, 0x67, 0x65, 0x6e, 0xad, 0x74, 0x65, 0x73, 0x74, 0x6e, 0x65, 0x74, 0x2d, 0x76, 0x33, 0x31, 0x2e, 0x30, 0xa2, 0x6c, 0x76, 0xce, 0x0, 0xe, 0xda, 0xc4, 0xa4, 0x6e, 0x6f, 0x74, 0x65, 0xc4, 0x8, 0xb4, 0x51, 0x79, 0x39, 0xfc, 0xfa, 0xd2, 0x71, 0xa3, 0x72, 0x63, 0x76, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa3, 0x73, 0x6e, 0x64, 0xc4, 0x20, 0xb4, 0xc6, 0x22, 0x68, 0xa4, 0xc3, 0x35, 0x50, 0xf5, 0x8a, 0x6d, 0xd4, 0xb8, 0xca, 0x23, 0x9c, 0x9f, 0x1d, 0x10, 0xb3, 0x41, 0xaa, 0x7e, 0x1a, 0x36, 0xe3, 0xce, 0x61, 0xfb, 0xfc, 0xf9, 0x8a, 0xa4, 0x74, 0x79, 0x70, 0x65, 0xa3, 0x70, 0x61, 0x79} 688 expectedTxid := "U4X24Q45MCZ6JSL343QNR3RC6AJO2NUDQXFCTNONIW3SU2AYQJOA" 689 expectedAuthAddr := maAddr 690 sender := otherAddr 691 testSign(t, lsigAccount, sender, expectedBytes, expectedTxid, expectedAuthAddr) 692 }) 693 }) 694 } 695 696 func TestTealSign(t *testing.T) { 697 data, err := base64.StdEncoding.DecodeString("Ux8jntyBJQarjKGF8A==") 698 require.NoError(t, err) 699 700 seed, err := base64.StdEncoding.DecodeString("5Pf7eGMA52qfMT4R4/vYCt7con/7U3yejkdXkrcb26Q=") 701 require.NoError(t, err) 702 sk := ed25519.NewKeyFromSeed(seed) 703 704 addr, err := types.DecodeAddress("6Z3C3LDVWGMX23BMSYMANACQOSINPFIRF77H7N3AWJZYV6OH6GWTJKVMXY") 705 require.NoError(t, err) 706 707 prog, err := base64.StdEncoding.DecodeString("ASABASI=") 708 require.NoError(t, err) 709 710 sig1, err := TealSign(sk, data, addr) 711 require.NoError(t, err) 712 713 sig2, err := TealSignFromProgram(sk, data, prog) 714 require.NoError(t, err) 715 716 require.Equal(t, sig1, sig2) 717 718 pk := sk.Public().(ed25519.PublicKey) 719 verified := TealVerify(pk, data, addr, sig1) 720 require.True(t, verified) 721 722 data[0] += 1 723 verified2 := TealVerify(pk, data, addr, sig1) 724 require.False(t, verified2) 725 } 726 727 func TestGetApplicationAddress(t *testing.T) { 728 appID := uint64(77) 729 expected := "PCYUFPA2ZTOYWTP43MX2MOX2OWAIAXUDNC2WFCXAGMRUZ3DYD6BWFDL5YM" 730 731 actual := GetApplicationAddress(appID) 732 require.Equal(t, expected, actual.String()) 733 }