github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/types/extrinsic_test.go (about)

     1  // Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
     2  //
     3  // Copyright 2020 Stafi Protocol
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package types_test
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/stafiprotocol/go-substrate-rpc-client/signature"
    24  	. "github.com/stafiprotocol/go-substrate-rpc-client/types"
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  func TestExtrinsic_Unsigned_EncodeDecode(t *testing.T) {
    29  	addr, err := NewAddressFromHexAccountID("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")
    30  	assert.NoError(t, err)
    31  
    32  	c, err := NewCall(ExamplaryMetadataV4, "balances.transfer", addr, NewUCompactFromUInt(6969))
    33  	assert.NoError(t, err)
    34  
    35  	ext := NewExtrinsic(c)
    36  
    37  	extEnc, err := EncodeToHexString(ext)
    38  	assert.NoError(t, err)
    39  
    40  	assert.Equal(t, "0x"+
    41  		"98"+ // length prefix, compact
    42  		"04"+ // version
    43  		"0300"+ // call index (section index and method index)
    44  		"ff"+
    45  		"8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"+ // target address
    46  		"e56c", // amount, compact
    47  		extEnc)
    48  
    49  	var extDec Extrinsic
    50  	err = DecodeFromHexString(extEnc, &extDec)
    51  	assert.NoError(t, err)
    52  
    53  	assert.Equal(t, ext, extDec)
    54  }
    55  
    56  func TestExtrinsic_Signed_EncodeDecode(t *testing.T) {
    57  	extEnc, err := EncodeToHexString(ExamplaryExtrinsic)
    58  	assert.NoError(t, err)
    59  
    60  	var extDec Extrinsic
    61  	err = DecodeFromHexString(extEnc, &extDec)
    62  	assert.NoError(t, err)
    63  
    64  	assert.Equal(t, ExamplaryExtrinsic, extDec)
    65  }
    66  
    67  func TestExtrinsic_Sign(t *testing.T) {
    68  	c, err := NewCall(ExamplaryMetadataV4,
    69  		"balances.transfer", NewAddressFromAccountID(MustHexDecodeString(
    70  			"0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")),
    71  		NewUCompactFromUInt(6969))
    72  	assert.NoError(t, err)
    73  
    74  	ext := NewExtrinsic(c)
    75  
    76  	o := SignatureOptions{
    77  		BlockHash: NewHash(MustHexDecodeString("0xec7afaf1cca720ce88c1d1b689d81f0583cc15a97d621cf046dd9abf605ef22f")),
    78  		// Era: ExtrinsicEra{IsImmortalEra: true},
    79  		GenesisHash:        NewHash(MustHexDecodeString("0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b")),
    80  		Nonce:              NewUCompactFromUInt(1),
    81  		SpecVersion:        123,
    82  		Tip:                NewUCompactFromUInt(2),
    83  		TransactionVersion: 1,
    84  	}
    85  
    86  	assert.False(t, ext.IsSigned())
    87  
    88  	err = ext.Sign(signature.TestKeyringPairAlice, o)
    89  	assert.NoError(t, err)
    90  
    91  	// fmt.Printf("%#v", ext)
    92  
    93  	assert.True(t, ext.IsSigned())
    94  
    95  	extEnc, err := EncodeToHexString(ext)
    96  	assert.NoError(t, err)
    97  
    98  	// extEnc will have the structure of the following. It can't be tested, since the signature is different on every
    99  	// call to sign. Instead we verify here.
   100  	// "0x"+
   101  	// "2902"+ // length prefix, compact
   102  	// "83"+ // version
   103  	// "ff"+
   104  	// "d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"+ // signer address
   105  	// "6667a2afe5272b327c3886036d2906ceac90fe959377a2d47fa92b6ebe345318379fff37e48a4e8fd552221796dd6329d028f80237"+
   106  	// 		"ebc0abb229ca2235778308"+ // signature
   107  	// "000408"+ // era, nonce, tip
   108  	// "0300" + // call index (section index and method index)
   109  	// "ff"+
   110  	// "8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"+ // target address
   111  	// "e56c", // amount, compact
   112  
   113  	var extDec Extrinsic
   114  	err = DecodeFromHexString(extEnc, &extDec)
   115  	assert.NoError(t, err)
   116  
   117  	assert.Equal(t, uint8(ExtrinsicVersion4), extDec.Type())
   118  	assert.Equal(t, signature.TestKeyringPairAlice.PublicKey, extDec.Signature.Signer.AsAccountID[:])
   119  
   120  	mb, err := EncodeToBytes(extDec.Method)
   121  	assert.NoError(t, err)
   122  
   123  	verifyPayload := ExtrinsicPayloadV4{
   124  		ExtrinsicPayloadV3: ExtrinsicPayloadV3{
   125  			Method:      mb,
   126  			Era:         extDec.Signature.Era,
   127  			Nonce:       extDec.Signature.Nonce,
   128  			Tip:         extDec.Signature.Tip,
   129  			SpecVersion: o.SpecVersion,
   130  			GenesisHash: o.GenesisHash,
   131  			BlockHash:   o.BlockHash,
   132  		},
   133  		TransactionVersion: 1,
   134  	}
   135  
   136  	// verify sig
   137  	b, err := EncodeToBytes(verifyPayload)
   138  	assert.NoError(t, err)
   139  	ok, err := signature.Verify(b, extDec.Signature.Signature.AsSr25519[:], HexEncodeToString(signature.TestKeyringPairAlice.PublicKey))
   140  	assert.NoError(t, err)
   141  	assert.True(t, ok)
   142  }
   143  
   144  func ExampleExtrinsic() {
   145  	bob, err := NewAddressFromHexAccountID("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")
   146  	if err != nil {
   147  		panic(err)
   148  	}
   149  
   150  	c, err := NewCall(ExamplaryMetadataV4, "balances.transfer", bob, NewUCompactFromUInt(6969))
   151  	if err != nil {
   152  		panic(err)
   153  	}
   154  
   155  	ext := NewExtrinsic(c)
   156  
   157  	ext.Method.CallIndex.SectionIndex = 5
   158  	ext.Method.CallIndex.MethodIndex = 0
   159  
   160  	era := ExtrinsicEra{IsMortalEra: true, AsMortalEra: MortalEra{0x95, 0x00}}
   161  
   162  	o := SignatureOptions{
   163  		BlockHash:   NewHash(MustHexDecodeString("0x223e3eb79416e6258d262b3a76e827aa0886b884a96bf96395cdd1c52d0eeb45")),
   164  		Era:         era,
   165  		GenesisHash: NewHash(MustHexDecodeString("0x81ad0bfe2a0bccd91d2e89852d79b7ff696d4714758e5f7c6f17ec7527e1f550")),
   166  		Nonce:       NewUCompactFromUInt(1),
   167  		SpecVersion: 170,
   168  		Tip:         NewUCompactFromUInt(0),
   169  	}
   170  
   171  	err = ext.Sign(signature.TestKeyringPairAlice, o)
   172  	if err != nil {
   173  		panic(err)
   174  	}
   175  
   176  	fmt.Printf("%#v", ext)
   177  
   178  	extEnc, err := EncodeToHexString(ext)
   179  	if err != nil {
   180  		panic(err)
   181  	}
   182  
   183  	fmt.Printf("%#v", extEnc)
   184  }
   185  
   186  func TestCall(t *testing.T) {
   187  	c := Call{CallIndex{6, 1}, Args{0, 0, 0}}
   188  
   189  	enc, err := EncodeToHexString(c)
   190  	assert.NoError(t, err)
   191  	assert.Equal(t, "0x0601000000", enc)
   192  }
   193  
   194  func TestNewCallV4(t *testing.T) {
   195  	addr, err := NewAddressFromHexAccountID("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")
   196  	assert.NoError(t, err)
   197  
   198  	c, err := NewCall(ExamplaryMetadataV4, "balances.transfer", addr, NewUCompactFromUInt(1000))
   199  	assert.NoError(t, err)
   200  
   201  	enc, err := EncodeToHexString(c)
   202  	assert.NoError(t, err)
   203  
   204  	assert.Equal(t, "0x0300ff8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f", enc)
   205  }
   206  
   207  func TestNewCallV7(t *testing.T) {
   208  	c, err := NewCall(&exampleMetadataV7, "Module2.my function", U8(3))
   209  	assert.NoError(t, err)
   210  
   211  	enc, err := EncodeToHexString(c)
   212  	assert.NoError(t, err)
   213  
   214  	assert.Equal(t, "0x010003", enc)
   215  }
   216  
   217  func TestNewCallV8(t *testing.T) {
   218  	c, err := NewCall(&exampleMetadataV8, "Module2.my function", U8(3))
   219  	assert.NoError(t, err)
   220  
   221  	enc, err := EncodeToHexString(c)
   222  	assert.NoError(t, err)
   223  
   224  	assert.Equal(t, "0x010003", enc)
   225  }