forked from TrueCloudLab/neoneo-go
Merge pull request #579 from nspcc-dev/refactor-crypto
This moves some functionality into micro-packages, improves testing, unexports some code and fixes bugs along the way.
This commit is contained in:
commit
9145855d2c
30 changed files with 284 additions and 157 deletions
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/CityOfZion/neo-go/config"
|
||||
"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/network"
|
||||
"github.com/CityOfZion/neo-go/pkg/network/metrics"
|
||||
|
@ -361,6 +362,9 @@ func initBlockChain(cfg config.Config) (*core.Blockchain, error) {
|
|||
if err != nil {
|
||||
return nil, cli.NewExitError(fmt.Errorf("could not initialize blockchain: %s", err), 1)
|
||||
}
|
||||
if cfg.ProtocolConfiguration.AddressVersion != 0 {
|
||||
address.Prefix = cfg.ProtocolConfiguration.AddressVersion
|
||||
}
|
||||
return chain, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ type (
|
|||
// ProtocolConfiguration represents the protocol config.
|
||||
ProtocolConfiguration struct {
|
||||
Magic NetMode `yaml:"Magic"`
|
||||
AddressVersion int64 `yaml:"AddressVersion"`
|
||||
AddressVersion byte `yaml:"AddressVersion"`
|
||||
SecondsPerBlock int `yaml:"SecondsPerBlock"`
|
||||
LowPriorityThreshold float64 `yaml:"LowPriorityThreshold"`
|
||||
MaxTransactionsPerBlock int64 `yaml:"MaxTransactionsPerBlock"`
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/network"
|
||||
"github.com/CityOfZion/neo-go/pkg/rpc"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -72,7 +72,7 @@ func getWif(t *testing.B) *keys.WIF {
|
|||
// getTX returns Invocation transaction with some random attributes in order to have different hashes.
|
||||
func getTX(t *testing.B, wif *keys.WIF) *transaction.Transaction {
|
||||
fromAddress := wif.PrivateKey.Address()
|
||||
fromAddressHash, err := crypto.Uint160DecodeAddress(fromAddress)
|
||||
fromAddressHash, err := address.StringToUint160(fromAddress)
|
||||
require.NoError(t, err)
|
||||
|
||||
tx := &transaction.Transaction{
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
|
||||
)
|
||||
|
@ -674,7 +674,7 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
// contain double quotes that need to be stripped.
|
||||
addressStr := expr.Args[0].(*ast.BasicLit).Value
|
||||
addressStr = strings.Replace(addressStr, "\"", "", 2)
|
||||
uint160, err := crypto.Uint160DecodeAddress(addressStr)
|
||||
uint160, err := address.StringToUint160(addressStr)
|
||||
if err != nil {
|
||||
c.prog.Err = err
|
||||
return
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/Workiva/go-datastructures/queue"
|
||||
|
@ -30,13 +30,13 @@ func (b *Block) Header() *Header {
|
|||
}
|
||||
}
|
||||
|
||||
func merkleTreeFromTransactions(txes []*transaction.Transaction) (*crypto.MerkleTree, error) {
|
||||
func merkleTreeFromTransactions(txes []*transaction.Transaction) (*hash.MerkleTree, error) {
|
||||
hashes := make([]util.Uint256, len(txes))
|
||||
for i, tx := range txes {
|
||||
hashes[i] = tx.Hash()
|
||||
}
|
||||
|
||||
return crypto.NewMerkleTree(hashes)
|
||||
return hash.NewMerkleTree(hashes)
|
||||
}
|
||||
|
||||
// rebuildMerkleRoot rebuilds the merkleroot of the block.
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -34,7 +34,7 @@ func TestDecodeBlock1(t *testing.T) {
|
|||
assert.Equal(t, data["hash"].(string), block.Hash().StringLE())
|
||||
assert.Equal(t, data["previousblockhash"].(string), block.PrevHash.StringLE())
|
||||
assert.Equal(t, data["merkleroot"].(string), block.MerkleRoot.StringLE())
|
||||
assert.Equal(t, data["nextconsensus"].(string), crypto.AddressFromUint160(block.NextConsensus))
|
||||
assert.Equal(t, data["nextconsensus"].(string), address.Uint160ToString(block.NextConsensus))
|
||||
|
||||
script := data["script"].(map[string]interface{})
|
||||
assert.Equal(t, script["invocation"].(string), hex.EncodeToString(block.Script.InvocationScript))
|
||||
|
@ -273,7 +273,7 @@ func TestBlockSizeCalculation(t *testing.T) {
|
|||
assert.Equal(t, 1527894405, int(b.Timestamp))
|
||||
assert.Equal(t, 2340363, int(b.Index))
|
||||
|
||||
nextConsensus := crypto.AddressFromUint160(b.NextConsensus)
|
||||
nextConsensus := address.Uint160ToString(b.NextConsensus)
|
||||
assert.Equal(t, "APyEx5f4Zm4oCHwFWiSTaph1fPBxZacYVR", nextConsensus)
|
||||
|
||||
assert.Equal(t, "4012afae6df64195041e4764b57caa9e27fc2cfc596833163904136ec95816d104b44b3737d0e9f6b1b4445cd3b6a5cc80f6b0935675bc44dba44415eb309832b3404dc95bcf85e4635556a1d618e4ce947b26972992ed74788df5f9501b850ac0b40b7112d1ff30e4ade00369e16f0d13932d1ba76725e7682db072f8e2cd7752b840d12bb7dd45dd3b0e2098db5c67b6de55b7c40164937491fcaca1239b25860251224ead23ab232add78ccccd347239eae50ffc98f50b2a84c60ec5c3d284647a7406fabf6ca241b759af6b71080c0dfad7395632e989226a7e52f8cd2c133aeb2226e6e1aea47666fd81f578405a9f9bbd9d0bc523c3a44d7a5099ddc649feabe5f406188b8ee478731a89beeb76fdbd108eb0071b8f2b8678f40c5a1f387a491314336783255dee8cc5af4bf914dfeaacecc318fc13e02262658e39e8ce0631941b1", hex.EncodeToString(b.Script.InvocationScript))
|
||||
|
|
|
@ -3,7 +3,7 @@ package transaction
|
|||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ func (out *Output) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal(map[string]interface{}{
|
||||
"asset": out.AssetID,
|
||||
"value": out.Amount,
|
||||
"address": crypto.AddressFromUint160(out.ScriptHash),
|
||||
"address": address.Uint160ToString(out.ScriptHash),
|
||||
"n": out.Position,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -58,7 +58,7 @@ func TestDecodeRegisterTXFromRawString(t *testing.T) {
|
|||
assert.Equal(t, util.Fixed8FromInt64(100000000), txData.Amount)
|
||||
assert.Equal(t, uint8(0), txData.Precision)
|
||||
assert.Equal(t, keys.PublicKey{}, txData.Owner)
|
||||
assert.Equal(t, "Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt", crypto.AddressFromUint160(txData.Admin))
|
||||
assert.Equal(t, "Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt", address.Uint160ToString(txData.Admin))
|
||||
assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().StringLE())
|
||||
|
||||
buf := io.NewBufBinWriter()
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
|
@ -51,8 +51,7 @@ func TestDecodeEncodeClaimTX(t *testing.T) {
|
|||
assert.Equal(t, 0, len(tx.Attributes))
|
||||
assert.Equal(t, 0, len(tx.Inputs))
|
||||
assert.Equal(t, 1, len(tx.Outputs))
|
||||
address := crypto.AddressFromUint160(tx.Outputs[0].ScriptHash)
|
||||
assert.Equal(t, "AQJseD8iBmCD4sgfHRhMahmoi9zvopG6yz", address)
|
||||
assert.Equal(t, "AQJseD8iBmCD4sgfHRhMahmoi9zvopG6yz", address.Uint160ToString(tx.Outputs[0].ScriptHash))
|
||||
assert.Equal(t, "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7", tx.Outputs[0].AssetID.StringLE())
|
||||
assert.Equal(t, tx.Outputs[0].Amount.String(), "0.06247739")
|
||||
invoc := "40456349cec43053009accdb7781b0799c6b591c812768804ab0a0b56b5eae7a97694227fcd33e70899c075848b2cee8fae733faac6865b484d3f7df8949e2aadb"
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/config"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -45,7 +45,7 @@ func TestGetConsensusAddressMainNet(t *testing.T) {
|
|||
}
|
||||
|
||||
assert.Equal(t, consensusScript, script.String())
|
||||
assert.Equal(t, consensusAddr, crypto.AddressFromUint160(script))
|
||||
assert.Equal(t, consensusAddr, address.Uint160ToString(script))
|
||||
}
|
||||
|
||||
func TestUtilityTokenTX(t *testing.T) {
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// AddressFromUint160 returns the "NEO address" from the given
|
||||
// Uint160.
|
||||
func AddressFromUint160(u util.Uint160) string {
|
||||
// Dont forget to prepend the Address version 0x17 (23) A
|
||||
b := append([]byte{0x17}, u.BytesBE()...)
|
||||
return Base58CheckEncode(b)
|
||||
}
|
||||
|
||||
// Uint160DecodeAddress attempts to decode the given NEO address string
|
||||
// into an Uint160.
|
||||
func Uint160DecodeAddress(s string) (u util.Uint160, err error) {
|
||||
b, err := Base58CheckDecode(s)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
return util.Uint160DecodeBytesBE(b[1:21])
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package crypto
|
||||
package hash
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
|
@ -26,13 +25,8 @@ func NewMerkleTree(hashes []util.Uint256) (*MerkleTree, error) {
|
|||
}
|
||||
}
|
||||
|
||||
root, err := buildMerkleTree(nodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &MerkleTree{
|
||||
root: root,
|
||||
root: buildMerkleTree(nodes),
|
||||
depth: 1,
|
||||
}, nil
|
||||
}
|
||||
|
@ -42,12 +36,12 @@ func (t *MerkleTree) Root() util.Uint256 {
|
|||
return t.root.hash
|
||||
}
|
||||
|
||||
func buildMerkleTree(leaves []*MerkleTreeNode) (*MerkleTreeNode, error) {
|
||||
func buildMerkleTree(leaves []*MerkleTreeNode) *MerkleTreeNode {
|
||||
if len(leaves) == 0 {
|
||||
return nil, errors.New("length of the leaves cannot be zero")
|
||||
panic("length of leaves cannot be zero")
|
||||
}
|
||||
if len(leaves) == 1 {
|
||||
return leaves[0], nil
|
||||
return leaves[0]
|
||||
}
|
||||
|
||||
parents := make([]*MerkleTreeNode, (len(leaves)+1)/2)
|
||||
|
@ -66,7 +60,7 @@ func buildMerkleTree(leaves []*MerkleTreeNode) (*MerkleTreeNode, error) {
|
|||
b1 := parents[i].leftChild.hash.BytesBE()
|
||||
b2 := parents[i].rightChild.hash.BytesBE()
|
||||
b1 = append(b1, b2...)
|
||||
parents[i].hash = hash.DoubleSha256(b1)
|
||||
parents[i].hash = DoubleSha256(b1)
|
||||
}
|
||||
|
||||
return buildMerkleTree(parents)
|
103
pkg/crypto/hash/merkle_tree_test.go
Normal file
103
pkg/crypto/hash/merkle_tree_test.go
Normal file
|
@ -0,0 +1,103 @@
|
|||
package hash
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func testComputeMerkleTree(t *testing.T, hexHashes []string, result string) {
|
||||
hashes := make([]util.Uint256, len(hexHashes))
|
||||
for i, str := range hexHashes {
|
||||
hash, err := util.Uint256DecodeStringLE(str)
|
||||
require.NoError(t, err)
|
||||
hashes[i] = hash
|
||||
}
|
||||
|
||||
merkle, err := NewMerkleTree(hashes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, result, merkle.Root().StringLE())
|
||||
assert.Equal(t, true, merkle.root.IsRoot())
|
||||
assert.Equal(t, false, merkle.root.IsLeaf())
|
||||
leaf := merkle.root
|
||||
for leaf.leftChild != nil || leaf.rightChild != nil {
|
||||
if leaf.leftChild != nil {
|
||||
leaf = leaf.leftChild
|
||||
continue
|
||||
}
|
||||
leaf = leaf.rightChild
|
||||
}
|
||||
assert.Equal(t, true, leaf.IsLeaf())
|
||||
assert.Equal(t, false, leaf.IsRoot())
|
||||
}
|
||||
|
||||
func TestComputeMerkleTree1(t *testing.T) {
|
||||
// Mainnet block #0
|
||||
rawHashes := []string{
|
||||
"fb5bd72b2d6792d75dc2f1084ffa9e9f70ca85543c717a6b13d9959b452a57d6",
|
||||
"c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
|
||||
"602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7",
|
||||
"3631f66024ca6f5b033d7e0809eb993443374830025af904fb51b0334f127cda",
|
||||
}
|
||||
res := "803ff4abe3ea6533bcc0be574efa02f83ae8fdc651c879056b0d9be336c01bf4"
|
||||
testComputeMerkleTree(t, rawHashes, res)
|
||||
}
|
||||
|
||||
func TestComputeMerkleTree2(t *testing.T) {
|
||||
// Mainnet block #4635525
|
||||
rawHashes := []string{
|
||||
"c832ef573136eae2c57a35989d3fb9b3a135d08ffa0faa49d8766f7c1a92ca0f",
|
||||
"b8606dfeb126a5963d6674f8dbfb786db7f6c27800167c3eef56ff7110ff0ffc",
|
||||
"498a5d58179002dd9db7b23df657ecf7e1b2e8218bd48dda035e5accc664830a",
|
||||
"5c350282b448c139adb1f5e3fba0e9326476a38c01ea88876ebc4a882c472d42",
|
||||
"cea31cc85e7310183561d4f420026984ba48354516f9274c44b52c7f9a5c6107",
|
||||
"744f985dd5ad6f4ad6376376b48552abf7755b2ebc5c6271950714f848d1cc3a",
|
||||
"02c5fc225b6ead91f73a7b3ebb19bb30a113baea60f439b654c2811d630a2c48",
|
||||
"2b3478e0fa91db3a309caeb4d9739f38233c1c189d6fa7e159e24afce9fae082",
|
||||
"4d50693cee3ac2c976c092620834d4da264583cf15a1d11dd65d0e94861d49e0",
|
||||
"5f179efae999f8f8086269cedd1fbfaf6e90aadf5369a12737db0fff5905b12e",
|
||||
"6ef2237b6c8683f626269027050c45cc4be89042ee99e4e89bfd9d9fbd24da19",
|
||||
"6fd5154af55b4a1e4a1a5272e33238b2a2da12a30fa06af4f740d207e54ed495",
|
||||
}
|
||||
res := "42489ad8043a834149cd8e406c90c61411a05a0ca9f8e921b456a00b5d5988d7"
|
||||
testComputeMerkleTree(t, rawHashes, res)
|
||||
}
|
||||
|
||||
func TestComputeMerkleTree3(t *testing.T) {
|
||||
// Mainnet block #2097152
|
||||
rawHashes := []string{
|
||||
"a7ff2c6aa08d4b979d5f7605aec5a1783c9207c738b5852ed5ff17b37ada649d",
|
||||
"34fd42c1f47aa306ad2fd0fc04437fd5c828a25b3de59e73b18157253094a8da",
|
||||
"36458dffd678d9f75ed9f2a28beb58bf1ad739f8899469b8641b0ddea22fcf5d",
|
||||
"3e8144abe2edda263593f24defd4557d403efa1b4fa839409ac217d6f8a87d3a",
|
||||
"a1d2cf73841fefcd21ca9986c664518d2af61edcfe3a97b30b3cc58fab4e61f6",
|
||||
"c1e868aef0e8fd76b95a18e155b1fa65f30d0a4887bc953411553728664725bc",
|
||||
"52d2fda0fe0fd586063d801c5ba77ca123a790d7e4dae34c53398feab36da721",
|
||||
"fdf8d4610cb2de35ab4c18d38357b86c52966d149c8975906170dc513cc26345",
|
||||
"35a26a11ef65d8f7a2424f7ce5915aa1d8bf3449018516003799767c2696197e",
|
||||
"c9d251abfc20a0d6eeac2d5a93b77a6a0632a679a07decea2c809aead89bb503",
|
||||
"d92c72873f2929c621ec06433da3053db25ee396b70c83d53abd40801823f66c",
|
||||
}
|
||||
res := "09c2dbc88810c350a2e7ace56bb1b371b2a2b5c4744e7a303adace9a2c2bbf6d"
|
||||
testComputeMerkleTree(t, rawHashes, res)
|
||||
}
|
||||
|
||||
func TestNewMerkleTreeFailWithoutHashes(t *testing.T) {
|
||||
var hashes []util.Uint256
|
||||
_, err := NewMerkleTree(hashes)
|
||||
require.Error(t, err)
|
||||
hashes = make([]util.Uint256, 0)
|
||||
_, err = NewMerkleTree(hashes)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestBuildMerkleTreeWithoutNodes(t *testing.T) {
|
||||
var leaves []*MerkleTreeNode
|
||||
require.Panics(t, func() { buildMerkleTree(leaves) })
|
||||
leaves = make([]*MerkleTreeNode, 0)
|
||||
require.Panics(t, func() { buildMerkleTree(leaves) })
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package crypto
|
||||
package keys
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
)
|
||||
|
||||
// AESEncrypt encrypts the key with the given source.
|
||||
func AESEncrypt(src, key []byte) ([]byte, error) {
|
||||
// aesEncrypt encrypts the key with the given source.
|
||||
func aesEncrypt(src, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -19,8 +19,8 @@ func AESEncrypt(src, key []byte) ([]byte, error) {
|
|||
return out, nil
|
||||
}
|
||||
|
||||
// AESDecrypt decrypts the encrypted source with the given key.
|
||||
func AESDecrypt(crypted, key []byte) ([]byte, error) {
|
||||
// aesDecrypt decrypts the encrypted source with the given key.
|
||||
func aesDecrypt(crypted, key []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
|
@ -5,8 +5,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/base58"
|
||||
"golang.org/x/crypto/scrypt"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
@ -57,7 +57,7 @@ func NEP2Encrypt(priv *PrivateKey, passphrase string) (s string, err error) {
|
|||
derivedKey2 := derivedKey[32:]
|
||||
xr := xor(priv.Bytes(), derivedKey1)
|
||||
|
||||
encrypted, err := crypto.AESEncrypt(xr, derivedKey2)
|
||||
encrypted, err := aesEncrypt(xr, derivedKey2)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
@ -72,13 +72,13 @@ func NEP2Encrypt(priv *PrivateKey, passphrase string) (s string, err error) {
|
|||
return s, fmt.Errorf("invalid buffer length: expecting 39 bytes got %d", buf.Len())
|
||||
}
|
||||
|
||||
return crypto.Base58CheckEncode(buf.Bytes()), nil
|
||||
return base58.CheckEncode(buf.Bytes()), nil
|
||||
}
|
||||
|
||||
// NEP2Decrypt decrypts an encrypted key using a given passphrase
|
||||
// under the NEP-2 standard.
|
||||
func NEP2Decrypt(key, passphrase string) (s string, err error) {
|
||||
b, err := crypto.Base58CheckDecode(key)
|
||||
b, err := base58.CheckDecode(key)
|
||||
if err != nil {
|
||||
return s, nil
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ func NEP2Decrypt(key, passphrase string) (s string, err error) {
|
|||
derivedKey2 := derivedKey[32:]
|
||||
encryptedBytes := b[7:]
|
||||
|
||||
decrypted, err := crypto.AESDecrypt(encryptedBytes, derivedKey2)
|
||||
decrypted, err := aesDecrypt(encryptedBytes, derivedKey2)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -173,6 +173,8 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
|||
return
|
||||
}
|
||||
|
||||
p256 := elliptic.P256()
|
||||
p256Params := p256.Params()
|
||||
// Infinity
|
||||
switch prefix {
|
||||
case 0x00:
|
||||
|
@ -189,6 +191,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
|||
ylsb := uint(prefix & 0x1)
|
||||
y, err = decodeCompressedY(x, ylsb)
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
case 0x04:
|
||||
|
@ -201,17 +204,15 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
|||
}
|
||||
x = new(big.Int).SetBytes(xbytes)
|
||||
y = new(big.Int).SetBytes(ybytes)
|
||||
if !p256.IsOnCurve(x, y) {
|
||||
r.Err = errors.New("encoded point is not on the P256 curve")
|
||||
return
|
||||
}
|
||||
default:
|
||||
r.Err = errors.Errorf("invalid prefix %d", prefix)
|
||||
return
|
||||
}
|
||||
c := elliptic.P256()
|
||||
cp := c.Params()
|
||||
if !c.IsOnCurve(x, y) {
|
||||
r.Err = errors.New("enccoded point is not on the P256 curve")
|
||||
return
|
||||
}
|
||||
if x.Cmp(cp.P) >= 0 || y.Cmp(cp.P) >= 0 {
|
||||
if x.Cmp(p256Params.P) >= 0 || y.Cmp(p256Params.P) >= 0 {
|
||||
r.Err = errors.New("enccoded point is not correct (X or Y is bigger than P")
|
||||
return
|
||||
}
|
||||
|
@ -242,11 +243,9 @@ func (p *PublicKey) Signature() []byte {
|
|||
|
||||
// Address returns a base58-encoded NEO-specific address based on the key hash.
|
||||
func (p *PublicKey) Address() string {
|
||||
var b = p.Signature()
|
||||
sig := hash.Hash160(p.GetVerificationScript())
|
||||
|
||||
b = append([]byte{0x17}, b...)
|
||||
|
||||
return crypto.Base58CheckEncode(b)
|
||||
return address.Uint160ToString(sig)
|
||||
}
|
||||
|
||||
// Verify returns true if the signature is valid and corresponds
|
||||
|
|
|
@ -63,6 +63,30 @@ func TestDecodeFromString(t *testing.T) {
|
|||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDecodeFromStringBadCompressed(t *testing.T) {
|
||||
str := "02ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
_, err := NewPublicKeyFromString(str)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDecodeFromStringBadXMoreThanP(t *testing.T) {
|
||||
str := "02ffffffff00000001000000000000000000000001ffffffffffffffffffffffff"
|
||||
_, err := NewPublicKeyFromString(str)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDecodeFromStringNotOnCurve(t *testing.T) {
|
||||
str := "04ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
_, err := NewPublicKeyFromString(str)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDecodeFromStringUncompressed(t *testing.T) {
|
||||
str := "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
|
||||
_, err := NewPublicKeyFromString(str)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestPubkeyToAddress(t *testing.T) {
|
||||
pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/base58"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -43,13 +43,13 @@ func WIFEncode(key []byte, version byte, compressed bool) (s string, err error)
|
|||
buf.WriteByte(0x01)
|
||||
}
|
||||
|
||||
s = crypto.Base58CheckEncode(buf.Bytes())
|
||||
s = base58.CheckEncode(buf.Bytes())
|
||||
return
|
||||
}
|
||||
|
||||
// WIFDecode decodes the given WIF string into a WIF struct.
|
||||
func WIFDecode(wif string, version byte) (*WIF, error) {
|
||||
b, err := crypto.Base58CheckDecode(wif)
|
||||
b, err := base58.CheckDecode(wif)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestComputeMerkleTree(t *testing.T) {
|
||||
rawHashes := []string{
|
||||
"fb5bd72b2d6792d75dc2f1084ffa9e9f70ca85543c717a6b13d9959b452a57d6",
|
||||
"c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
|
||||
"602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7",
|
||||
"3631f66024ca6f5b033d7e0809eb993443374830025af904fb51b0334f127cda",
|
||||
}
|
||||
|
||||
hashes := make([]util.Uint256, len(rawHashes))
|
||||
for i, str := range rawHashes {
|
||||
hash, _ := util.Uint256DecodeStringLE(str)
|
||||
hashes[i] = hash
|
||||
}
|
||||
|
||||
merkle, err := NewMerkleTree(hashes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "803ff4abe3ea6533bcc0be574efa02f83ae8fdc651c879056b0d9be336c01bf4", merkle.Root().StringLE())
|
||||
}
|
32
pkg/encoding/address/address.go
Normal file
32
pkg/encoding/address/address.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package address
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/base58"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Prefix is the byte used to prepend to addresses when encoding them, it can
|
||||
// be changed and defaults to 23 (0x17), the standard NEO prefix.
|
||||
var Prefix = byte(0x17)
|
||||
|
||||
// Uint160ToString returns the "NEO address" from the given Uint160.
|
||||
func Uint160ToString(u util.Uint160) string {
|
||||
// Dont forget to prepend the Address version 0x17 (23) A
|
||||
b := append([]byte{Prefix}, u.BytesBE()...)
|
||||
return base58.CheckEncode(b)
|
||||
}
|
||||
|
||||
// StringToUint160 attempts to decode the given NEO address string
|
||||
// into an Uint160.
|
||||
func StringToUint160(s string) (u util.Uint160, err error) {
|
||||
b, err := base58.CheckDecode(s)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
if b[0] != Prefix {
|
||||
return u, errors.New("wrong address prefix")
|
||||
}
|
||||
return util.Uint160DecodeBytesBE(b[1:21])
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
package crypto
|
||||
package address
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUint160DecodeEncodeAddress(t *testing.T) {
|
||||
|
@ -13,18 +14,18 @@ func TestUint160DecodeEncodeAddress(t *testing.T) {
|
|||
"AMxkaxFVG8Q1BhnB4fjTA5ZmUTEnnTMJMa",
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
val, err := Uint160DecodeAddress(addr)
|
||||
val, err := StringToUint160(addr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, addr, AddressFromUint160(val))
|
||||
assert.Equal(t, addr, Uint160ToString(val))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUint160DecodeKnownAddress(t *testing.T) {
|
||||
address := "AJeAEsmeD6t279Dx4n2HWdUvUmmXQ4iJvP"
|
||||
|
||||
val, err := Uint160DecodeAddress(address)
|
||||
val, err := StringToUint160(address)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -32,3 +33,18 @@ func TestUint160DecodeKnownAddress(t *testing.T) {
|
|||
assert.Equal(t, "b28427088a3729b2536d10122960394e8be6721f", val.StringLE())
|
||||
assert.Equal(t, "1f72e68b4e39602912106d53b229378a082784b2", val.String())
|
||||
}
|
||||
|
||||
func TestUint160DecodeBadBase58(t *testing.T) {
|
||||
address := "AJeAEsmeD6t279Dx4n2HWdUvUmmXQ4iJv@"
|
||||
|
||||
_, err := StringToUint160(address)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestUint160DecodeBadPrefix(t *testing.T) {
|
||||
// The same AJeAEsmeD6t279Dx4n2HWdUvUmmXQ4iJvP key encoded with 0x18 prefix.
|
||||
address := "AhymDz4vvHLtvaN36CMbzkki7H2U8ENb8F"
|
||||
|
||||
_, err := StringToUint160(address)
|
||||
require.Error(t, err)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package crypto
|
||||
package base58
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -8,20 +8,14 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Base58CheckDecode decodes the given string.
|
||||
func Base58CheckDecode(s string) (b []byte, err error) {
|
||||
// CheckDecode implements a base58-encoded string decoding with hash-based
|
||||
// checksum check.
|
||||
func CheckDecode(s string) (b []byte, err error) {
|
||||
b, err = base58.Decode(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] != '1' {
|
||||
break
|
||||
}
|
||||
b = append([]byte{0x00}, b...)
|
||||
}
|
||||
|
||||
if len(b) < 5 {
|
||||
return nil, errors.New("invalid base-58 check string: missing checksum")
|
||||
}
|
||||
|
@ -36,8 +30,9 @@ func Base58CheckDecode(s string) (b []byte, err error) {
|
|||
return b, nil
|
||||
}
|
||||
|
||||
// Base58CheckEncode encodes b into a base-58 check encoded string.
|
||||
func Base58CheckEncode(b []byte) string {
|
||||
// CheckEncode encodes given byte slice into a base58 string with hash-based
|
||||
// checksum appended to it.
|
||||
func CheckEncode(b []byte) string {
|
||||
b = append(b, hash.Checksum(b)...)
|
||||
|
||||
return base58.Encode(b)
|
|
@ -1,32 +1,41 @@
|
|||
package crypto
|
||||
package base58
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBase58CheckEncodeDecode(t *testing.T) {
|
||||
func TestCheckEncodeDecode(t *testing.T) {
|
||||
var b58CsumEncoded = "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9o"
|
||||
var b58CsumDecodedHex = "802bfe58ab6d9fd575bdc3a624e4825dd2b375d64ac033fbc46ea79dbab4f69a3e01"
|
||||
|
||||
b58CsumDecoded, _ := hex.DecodeString(b58CsumDecodedHex)
|
||||
encoded := Base58CheckEncode(b58CsumDecoded)
|
||||
decoded, err := Base58CheckDecode(b58CsumEncoded)
|
||||
encoded := CheckEncode(b58CsumDecoded)
|
||||
decoded, err := CheckDecode(b58CsumEncoded)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, encoded, b58CsumEncoded)
|
||||
assert.Equal(t, decoded, b58CsumDecoded)
|
||||
}
|
||||
|
||||
func TestBase58CheckDecodeFailures(t *testing.T) {
|
||||
func TestCheckDecodeFailures(t *testing.T) {
|
||||
badbase58 := "BASE%*"
|
||||
_, err := Base58CheckDecode(badbase58)
|
||||
_, err := CheckDecode(badbase58)
|
||||
assert.NotNil(t, err)
|
||||
shortbase58 := "THqY"
|
||||
_, err = Base58CheckDecode(shortbase58)
|
||||
_, err = CheckDecode(shortbase58)
|
||||
assert.NotNil(t, err)
|
||||
badcsum := "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9A"
|
||||
_, err = Base58CheckDecode(badcsum)
|
||||
_, err = CheckDecode(badcsum)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestBase58LeadingZeroes(t *testing.T) {
|
||||
buf := []byte{0, 0, 0, 1}
|
||||
b58 := CheckEncode(buf)
|
||||
dec, err := CheckDecode(b58)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, buf, dec)
|
||||
}
|
4
pkg/encoding/base58/doc.go
Normal file
4
pkg/encoding/base58/doc.go
Normal file
|
@ -0,0 +1,4 @@
|
|||
/*
|
||||
Package base58 wraps generic base58 encoder with NEO-specific checksumming.
|
||||
*/
|
||||
package base58
|
|
@ -6,7 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -96,7 +96,7 @@ func (p Param) GetUint160FromAddress() (util.Uint160, error) {
|
|||
return util.Uint160{}, err
|
||||
}
|
||||
|
||||
return crypto.Uint160DecodeAddress(s)
|
||||
return address.StringToUint160(s)
|
||||
}
|
||||
|
||||
// GetFuncParam returns current parameter as a function call parameter.
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -129,7 +129,7 @@ func TestParamGetUint160FromHex(t *testing.T) {
|
|||
|
||||
func TestParamGetUint160FromAddress(t *testing.T) {
|
||||
in := "AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y"
|
||||
u160, _ := crypto.Uint160DecodeAddress(in)
|
||||
u160, _ := address.StringToUint160(in)
|
||||
p := Param{stringT, in}
|
||||
u, err := p.GetUint160FromAddress()
|
||||
assert.Equal(t, u160, u)
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
|
@ -26,17 +26,17 @@ func CreateRawContractTransaction(params ContractTxParams) (*transaction.Transac
|
|||
fromAddress string
|
||||
receiverOutput *transaction.Output
|
||||
|
||||
wif, assetID, address, amount, balancer = params.wif, params.assetID, params.address, params.value, params.balancer
|
||||
wif, assetID, toAddress, amount, balancer = params.wif, params.assetID, params.address, params.value, params.balancer
|
||||
)
|
||||
|
||||
fromAddress = wif.PrivateKey.Address()
|
||||
|
||||
if fromAddressHash, err = crypto.Uint160DecodeAddress(fromAddress); err != nil {
|
||||
if fromAddressHash, err = address.StringToUint160(fromAddress); err != nil {
|
||||
return nil, errs.Wrapf(err, "Failed to take script hash from address: %v", fromAddress)
|
||||
}
|
||||
|
||||
if toAddressHash, err = crypto.Uint160DecodeAddress(address); err != nil {
|
||||
return nil, errs.Wrapf(err, "Failed to take script hash from address: %v", address)
|
||||
if toAddressHash, err = address.StringToUint160(toAddress); err != nil {
|
||||
return nil, errs.Wrapf(err, "Failed to take script hash from address: %v", toAddress)
|
||||
}
|
||||
tx.Attributes = append(tx.Attributes,
|
||||
transaction.Attribute{
|
||||
|
@ -58,12 +58,12 @@ func CreateRawContractTransaction(params ContractTxParams) (*transaction.Transac
|
|||
|
||||
// AddInputsAndUnspentsToTx adds inputs needed to transaction and one output
|
||||
// with change.
|
||||
func AddInputsAndUnspentsToTx(tx *transaction.Transaction, address string, assetID util.Uint256, amount util.Fixed8, balancer BalanceGetter) error {
|
||||
scriptHash, err := crypto.Uint160DecodeAddress(address)
|
||||
func AddInputsAndUnspentsToTx(tx *transaction.Transaction, addr string, assetID util.Uint256, amount util.Fixed8, balancer BalanceGetter) error {
|
||||
scriptHash, err := address.StringToUint160(addr)
|
||||
if err != nil {
|
||||
return errs.Wrapf(err, "failed to take script hash from address: %v", address)
|
||||
return errs.Wrapf(err, "failed to take script hash from address: %v", addr)
|
||||
}
|
||||
inputs, spent, err := balancer.CalculateInputs(address, assetID, amount)
|
||||
inputs, spent, err := balancer.CalculateInputs(addr, assetID, amount)
|
||||
if err != nil {
|
||||
return errs.Wrap(err, "failed to get inputs")
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package wrappers
|
|||
import (
|
||||
"github.com/CityOfZion/neo-go/pkg/core/state"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
|
@ -37,8 +37,8 @@ func NewAssetState(a *state.Asset) AssetState {
|
|||
FeeMode: a.FeeMode,
|
||||
FeeAddress: a.FeeAddress,
|
||||
Owner: a.Owner.String(),
|
||||
Admin: crypto.AddressFromUint160(a.Admin),
|
||||
Issuer: crypto.AddressFromUint160(a.Issuer),
|
||||
Admin: address.Uint160ToString(a.Admin),
|
||||
Issuer: address.Uint160ToString(a.Issuer),
|
||||
Expiration: a.Expiration,
|
||||
IsFrozen: a.IsFrozen,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package wrappers
|
||||
|
||||
import (
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
)
|
||||
|
||||
// ValidateAddressResponse represents response to validate address call.
|
||||
|
@ -12,10 +12,10 @@ type ValidateAddressResponse struct {
|
|||
|
||||
// ValidateAddress verifies that the address is a correct NEO address
|
||||
// see https://docs.neo.org/en-us/node/cli/2.9.4/api/validateaddress.html
|
||||
func ValidateAddress(address interface{}) ValidateAddressResponse {
|
||||
resp := ValidateAddressResponse{Address: address}
|
||||
if address, ok := address.(string); ok {
|
||||
_, err := crypto.Uint160DecodeAddress(address)
|
||||
func ValidateAddress(addr interface{}) ValidateAddressResponse {
|
||||
resp := ValidateAddressResponse{Address: addr}
|
||||
if addr, ok := addr.(string); ok {
|
||||
_, err := address.StringToUint160(addr)
|
||||
resp.IsValid = err == nil
|
||||
}
|
||||
return resp
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
||||
"github.com/CityOfZion/neo-go/pkg/io"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -156,7 +156,7 @@ func adjustValToType(typ ParamType, val string) (interface{}, error) {
|
|||
case IntegerType:
|
||||
return strconv.Atoi(val)
|
||||
case Hash160Type:
|
||||
u, err := crypto.Uint160DecodeAddress(val)
|
||||
u, err := address.StringToUint160(val)
|
||||
if err == nil {
|
||||
return hex.EncodeToString(u.BytesBE()), nil
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ func inferParamType(val string) ParamType {
|
|||
return BoolType
|
||||
}
|
||||
|
||||
_, err = crypto.Uint160DecodeAddress(val)
|
||||
_, err = address.StringToUint160(val)
|
||||
if err == nil {
|
||||
return Hash160Type
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue