github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/types/address.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 18 19 import ( 20 "fmt" 21 22 "github.com/stafiprotocol/go-substrate-rpc-client/pkg/scale" 23 ) 24 25 // Address is a wrapper around an AccountId or an AccountIndex. It is encoded with a prefix in case of an AccountID. 26 // Basically the Address is encoded as `[ <prefix-byte>, ...publicKey/...bytes ]` as per spec 27 type Address struct { 28 IsAccountID bool 29 AsAccountID AccountID 30 IsAccountIndex bool 31 AsAccountIndex AccountIndex 32 } 33 34 // NewAddressFromAccountID creates an Address from the given AccountID (public key) 35 func NewAddressFromAccountID(b []byte) Address { 36 return Address{ 37 IsAccountID: true, 38 AsAccountID: NewAccountID(b), 39 } 40 } 41 42 // NewAddressFromHexAccountID creates an Address from the given hex string that contains an AccountID (public key) 43 func NewAddressFromHexAccountID(str string) (Address, error) { 44 b, err := HexDecodeString(str) 45 if err != nil { 46 return Address{}, err 47 } 48 return NewAddressFromAccountID(b), nil 49 } 50 51 // NewAddressFromAccountIndex creates an Address from the given AccountIndex 52 func NewAddressFromAccountIndex(u uint32) Address { 53 return Address{ 54 IsAccountIndex: true, 55 AsAccountIndex: AccountIndex(u), 56 } 57 } 58 59 func (a *Address) Decode(decoder scale.Decoder) error { 60 b, err := decoder.ReadOneByte() 61 if err != nil { 62 return err 63 } 64 65 if defaultOptions.NoPalletIndices { 66 var sm [31]byte // Reading Address[32] minus b already read 67 err = decoder.Decode(&sm) 68 if err != nil { 69 return err 70 } 71 a.AsAccountID = NewAccountID(append([]byte{b}, sm[:]...)) // Push b back to the front 72 a.IsAccountID = true 73 return nil 74 } 75 76 if b == 0xff { 77 err = decoder.Decode(&a.AsAccountID) 78 a.IsAccountID = true 79 return err 80 } 81 82 if b == 0xfe { 83 return fmt.Errorf("decoding of Address with 0xfe prefix not supported") 84 } 85 86 if b == 0xfd { 87 err = decoder.Decode(&a.AsAccountIndex) 88 a.IsAccountIndex = true 89 return err 90 } 91 92 if b == 0xfc { 93 var aIndex uint16 94 err = decoder.Decode(&aIndex) 95 a.IsAccountIndex = true 96 a.AsAccountIndex = AccountIndex(aIndex) 97 return err 98 } 99 100 a.IsAccountIndex = true 101 a.AsAccountIndex = AccountIndex(b) 102 return nil 103 } 104 105 func (a Address) Encode(encoder scale.Encoder) error { 106 // type of address - public key 107 if a.IsAccountID { 108 if !defaultOptions.NoPalletIndices { // Skip in case target chain doesn't include indices pallet 109 err := encoder.PushByte(255) 110 if err != nil { 111 return err 112 } 113 } 114 115 err := encoder.Write(a.AsAccountID[:]) 116 if err != nil { 117 return err 118 } 119 120 return nil 121 } 122 123 if a.AsAccountIndex > 0xffff { 124 err := encoder.PushByte(253) 125 if err != nil { 126 return err 127 } 128 129 return encoder.Encode(a.AsAccountIndex) 130 } 131 132 if a.AsAccountIndex >= 0xf0 { 133 err := encoder.PushByte(252) 134 if err != nil { 135 return err 136 } 137 138 return encoder.Encode(uint16(a.AsAccountIndex)) 139 } 140 141 return encoder.Encode(uint8(a.AsAccountIndex)) 142 }