Merge pull request #1956 from nspcc-dev/interop/checksig-rename

core: rename Neo.Crypto.[CheckSig CheckMultisig] interops
This commit is contained in:
Roman Khimov 2021-05-12 17:06:39 +03:00 committed by GitHub
commit 75a55d910e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 754 additions and 750 deletions

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBdHR2qg==", "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBdHR2qg==", "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -44,11 +44,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF", "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUF7zmyl", "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NUREbqw2kfbPgDeEz8Dac2QxntGGqqFMm7", "address": "NMUedC8TSV2rE17wGguSvPk9XcmHSaT275",
"key": "6PYXADog3RQCwKRhqQsobwZEFopdcCJuMfPosM9pXPaDWSguKvznLdpADk", "key": "6PYSYoZaxqDu5vqvm7yUFT3sPJJFwyLyYDnp8zwj1YVPcBWxacz64bNX59",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG5BdHR2qg==", "script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG5BVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYXADog3RQCwKRhqQsobwZEFopdcCJuMfPosM9pXPaDWSguKvznLdpADk", "key": "6PYSYoZaxqDu5vqvm7yUFT3sPJJFwyLyYDnp8zwj1YVPcBWxacz64bNX59",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NQP81vKVRmwZHveX8C9Rbf2qejSpT1W1Eu", "address": "NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo",
"key": "6PYScv3Vgvdi9EkhDNvHXdvQeuaXK9gRwXDmytCswZMNpTzMLvfgR3U5dK", "key": "6PYVxMnzPMFTYY16xRvXm2SJcvaChabLzaARAb1Mmej9U7rYLYWMSPtfam",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5plBdHR2qg==", "script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5plBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYScv3Vgvdi9EkhDNvHXdvQeuaXK9gRwXDmytCswZMNpTzMLvfgR3U5dK", "key": "6PYVxMnzPMFTYY16xRvXm2SJcvaChabLzaARAb1Mmej9U7rYLYWMSPtfam",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NLA34vf8eXGGUhRjVaYe5f8YsyYHTehbDZ", "address": "NPrB7BmTMYxf9UVroJp4RQExM9tqKmsHTz",
"key": "6PYVwp1Sdg9DfTzvg42PZxgzMDf5a5FYBgT6ynKKzwmSHuhGkipoNjyW3a", "key": "6PYX8eELiDduPW3RGiZxZNmG6KtWtXkyRFi47f8w6quEBpRkpBPxH5u5AP",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWJBdHR2qg==", "script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYVwp1Sdg9DfTzvg42PZxgzMDf5a5FYBgT6ynKKzwmSHuhGkipoNjyW3a", "key": "6PYX8eELiDduPW3RGiZxZNmG6KtWtXkyRFi47f8w6quEBpRkpBPxH5u5AP",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -31,8 +31,8 @@ import (
const ( const (
validatorWIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY" validatorWIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY"
validatorAddr = "NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF" validatorAddr = "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP"
multisigAddr = "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6" multisigAddr = "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq"
validatorWallet = "testdata/wallet1_solo.json" validatorWallet = "testdata/wallet1_solo.json"
) )

View file

@ -22,7 +22,7 @@ import (
const ( const (
// nftOwnerAddr is the owner of NFT-ND HASHY token (../examples/nft-nd/nft.go) // nftOwnerAddr is the owner of NFT-ND HASHY token (../examples/nft-nd/nft.go)
nftOwnerAddr = "NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S" nftOwnerAddr = "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB"
nftOwnerWallet = "../examples/my_wallet.json" nftOwnerWallet = "../examples/my_wallet.json"
nftOwnerPass = "qwerty" nftOwnerPass = "qwerty"
) )

View file

@ -52,7 +52,7 @@ func TestNEP17Balance(t *testing.T) {
}) })
t.Run("all accounts", func(t *testing.T) { t.Run("all accounts", func(t *testing.T) {
e.Run(t, cmdbase...) e.Run(t, cmdbase...)
addr1, err := address.StringToUint160("NTh9TnZTstvAePEYWDGLLxidBikJE24uTo") addr1, err := address.StringToUint160("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
require.NoError(t, err) require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr1)) e.checkNextLine(t, "^Account "+address.Uint160ToString(addr1))
e.checkNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)") e.checkNextLine(t, "^\\s*GAS:\\s+GasToken \\("+e.Chain.UtilityTokenHash().StringLE()+"\\)")
@ -61,12 +61,12 @@ func TestNEP17Balance(t *testing.T) {
e.checkNextLine(t, "^\\s*Updated:") e.checkNextLine(t, "^\\s*Updated:")
e.checkNextLine(t, "^\\s*$") e.checkNextLine(t, "^\\s*$")
addr2, err := address.StringToUint160("NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6") addr2, err := address.StringToUint160("NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq")
require.NoError(t, err) require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr2)) e.checkNextLine(t, "^Account "+address.Uint160ToString(addr2))
e.checkNextLine(t, "^\\s*$") e.checkNextLine(t, "^\\s*$")
addr3, err := address.StringToUint160("NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF") addr3, err := address.StringToUint160("NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP")
require.NoError(t, err) require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr3)) e.checkNextLine(t, "^Account "+address.Uint160ToString(addr3))
// The order of assets is undefined. // The order of assets is undefined.
@ -86,7 +86,7 @@ func TestNEP17Balance(t *testing.T) {
} }
e.checkNextLine(t, "^\\s*$") e.checkNextLine(t, "^\\s*$")
addr4, err := address.StringToUint160("NaZjSxmRZ4ErG2QEXCQMjjJfvAxMPiutmi") // deployed verify.go contract addr4, err := address.StringToUint160("NQKpygA5oG8KRivZeYjXVU2T1ZPmUmaqQF") // deployed verify.go contract
require.NoError(t, err) require.NoError(t, err)
e.checkNextLine(t, "^Account "+address.Uint160ToString(addr4)) e.checkNextLine(t, "^Account "+address.Uint160ToString(addr4))
e.checkEOF(t) e.checkEOF(t)
@ -134,7 +134,7 @@ func TestNEP17Transfer(t *testing.T) {
require.Equal(t, big.NewInt(1), b) require.Equal(t, big.NewInt(1), b)
hVerify := deployVerifyContract(t, e) hVerify := deployVerifyContract(t, e)
const validatorDefault = "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo" const validatorDefault = "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn"
t.Run("default address", func(t *testing.T) { t.Run("default address", func(t *testing.T) {
e.In.WriteString("one\r") e.In.WriteString("one\r")

Binary file not shown.

View file

@ -1,31 +1,30 @@
{ {
"version": "3.0", "version": "3.0",
"extra" : {
"Tokens" : null
},
"accounts": [ "accounts": [
{ {
"lock" : false, "address": "Nfyz4KcsgYepRJw1W5C2uKCi6QWKf7v6gG",
"isdefault" : false, "key": "6PYVjvHy8n4suq81uxkWqriiffKWFpTFPve57HdzWdDhpYUUYRUTai1jZS",
"key" : "6PYRjaxsdSrW8zBzPynkC9uJRHpkhFHiQTuYY33gNL1wTimTbpN8S8eCNc", "label": "kek",
"address" : "NUSEsqon6PikQA5mDFaV4njemF9Su8JEmf",
"contract": { "contract": {
"script": "DCECl3UyEIq6T5RRIXS6z4tNdZPTzQ7NvXyx7FwK05d9UyZBVuezJw==",
"parameters": [ "parameters": [
{ {
"type" : "Signature", "name": "parameter0",
"name" : "parameter0" "type": "Signature"
} }
], ],
"script" : "DCECl3UyEIq6T5RRIXS6z4tNdZPTzQ7NvXyx7FwK05d9UyZBdHR2qg==",
"deployed": false "deployed": false
}, },
"label" : "kek" "lock": false,
"isdefault": false
} }
], ],
"scrypt": { "scrypt": {
"n": 16384,
"r": 8, "r": 8,
"p" : 8, "p": 8
"n" : 16384 },
"extra": {
"Tokens": null
} }
} }

View file

@ -1,56 +1,53 @@
{ {
"scrypt" : { "extra" : {
"r" : 8, "Tokens" : null
"p" : 8,
"n" : 16384
}, },
"version" : "3.0",
"accounts" : [ "accounts" : [
{ {
"address" : "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo",
"label" : "", "label" : "",
"key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"lock" : false, "lock" : false,
"isdefault" : true,
"contract" : { "contract" : {
"script" : "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"deployed" : false,
"parameters" : [ "parameters" : [
{ {
"type" : "Signature", "name" : "parameter0",
"name" : "parameter0" "type" : "Signature"
} }
], ]
"script" : "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBdHR2qg==",
"deployed" : false
}, },
"isdefault" : true, "address" : "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn"
"key" : "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL"
}, },
{ {
"label" : "", "lock" : false,
"address" : "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6",
"isdefault" : false, "isdefault" : false,
"key" : "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL",
"contract" : { "contract" : {
"script" : "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters" : [ "parameters" : [
{ {
"name" : "parameter0", "name" : "parameter0",
"type" : "Signature" "type" : "Signature"
}, },
{ {
"type" : "Signature", "name" : "parameter1",
"name" : "parameter1" "type" : "Signature"
}, },
{ {
"type" : "Signature", "type" : "Signature",
"name" : "parameter2" "name" : "parameter2"
} }
], ],
"deployed" : false, "deployed" : false
"script" : "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl"
}, },
"lock" : false "address" : "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"label" : "",
"key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY"
}, },
{ {
"address" : "NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF", "lock" : false,
"label" : "", "isdefault" : false,
"contract" : { "contract" : {
"parameters" : [ "parameters" : [
{ {
@ -59,26 +56,29 @@
} }
], ],
"deployed" : false, "deployed" : false,
"script" : "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUF7zmyl" "script" : "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6"
}, },
"lock" : false, "address" : "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP",
"isdefault" : false, "label" : "",
"key" : "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL" "key" : "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY"
}, },
{ {
"address" : "NQKpygA5oG8KRivZeYjXVU2T1ZPmUmaqQF",
"contract" : { "contract" : {
"parameters" : [],
"script" : "VwEAEdsgQFcAA0BXAQR4eXp7VBTAcAwOT25ORVAxMVBheW1lbnRoUEGVAW9hIUA=", "script" : "VwEAEdsgQFcAA0BXAQR4eXp7VBTAcAwOT25ORVAxMVBheW1lbnRoUEGVAW9hIUA=",
"parameters" : [],
"deployed" : true "deployed" : true
}, },
"lock" : false, "lock" : false,
"isdefault" : false, "isdefault" : false,
"key" : "6PYVxVpeNjxGDFTTG61ARGy6mCz6fQsGm9qW2tsFW3ox1zM6KpCoWSE4PB", "key" : "6PYSATFzuRXXUeq7tMDyA1AGxWdVcm7ftbkqtGBt69WJBapT1tkwjp1zpx",
"address" : "NaZjSxmRZ4ErG2QEXCQMjjJfvAxMPiutmi",
"label" : "acc" "label" : "acc"
} }
], ],
"extra" : { "version" : "3.0",
"Tokens" : null "scrypt" : {
"r" : 8,
"n" : 16384,
"p" : 8
} }
} }

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBdHR2qg==", "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -309,7 +309,7 @@ func TestWalletDump(t *testing.T) {
w := new(wallet.Wallet) w := new(wallet.Wallet)
require.NoError(t, json.Unmarshal([]byte(rawStr), w)) require.NoError(t, json.Unmarshal([]byte(rawStr), w))
require.Equal(t, 1, len(w.Accounts)) require.Equal(t, 1, len(w.Accounts))
require.Equal(t, "NUSEsqon6PikQA5mDFaV4njemF9Su8JEmf", w.Accounts[0].Address) require.Equal(t, "Nfyz4KcsgYepRJw1W5C2uKCi6QWKf7v6gG", w.Accounts[0].Address)
t.Run("with decrypt", func(t *testing.T) { t.Run("with decrypt", func(t *testing.T) {
cmd = append(cmd, "--decrypt") cmd = append(cmd, "--decrypt")
@ -324,7 +324,7 @@ func TestWalletDump(t *testing.T) {
w := new(wallet.Wallet) w := new(wallet.Wallet)
require.NoError(t, json.Unmarshal([]byte(rawStr), w)) require.NoError(t, json.Unmarshal([]byte(rawStr), w))
require.Equal(t, 1, len(w.Accounts)) require.Equal(t, 1, len(w.Accounts))
require.Equal(t, "NUSEsqon6PikQA5mDFaV4njemF9Su8JEmf", w.Accounts[0].Address) require.Equal(t, "Nfyz4KcsgYepRJw1W5C2uKCi6QWKf7v6gG", w.Accounts[0].Address)
}) })
} }
@ -334,27 +334,27 @@ func TestDumpKeys(t *testing.T) {
pubRegex := "^0[23][a-hA-H0-9]{64}$" pubRegex := "^0[23][a-hA-H0-9]{64}$"
t.Run("all", func(t *testing.T) { t.Run("all", func(t *testing.T) {
e.Run(t, cmd...) e.Run(t, cmd...)
e.checkNextLine(t, "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo") e.checkNextLine(t, "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
e.checkNextLine(t, pubRegex) e.checkNextLine(t, pubRegex)
e.checkNextLine(t, "^\\s*$") e.checkNextLine(t, "^\\s*$")
e.checkNextLine(t, "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6") e.checkNextLine(t, "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq")
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
e.checkNextLine(t, pubRegex) e.checkNextLine(t, pubRegex)
} }
e.checkNextLine(t, "^\\s*$") e.checkNextLine(t, "^\\s*$")
e.checkNextLine(t, "NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF") e.checkNextLine(t, "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP")
e.checkNextLine(t, pubRegex) e.checkNextLine(t, pubRegex)
e.checkEOF(t) e.checkEOF(t)
}) })
t.Run("simple signature", func(t *testing.T) { t.Run("simple signature", func(t *testing.T) {
cmd := append(cmd, "--address", "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo") cmd := append(cmd, "--address", "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
e.Run(t, cmd...) e.Run(t, cmd...)
e.checkNextLine(t, "simple signature contract") e.checkNextLine(t, "simple signature contract")
e.checkNextLine(t, pubRegex) e.checkNextLine(t, pubRegex)
e.checkEOF(t) e.checkEOF(t)
}) })
t.Run("3/4 multisig", func(t *testing.T) { t.Run("3/4 multisig", func(t *testing.T) {
cmd := append(cmd, "-a", "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6") cmd := append(cmd, "-a", "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq")
e.Run(t, cmd...) e.Run(t, cmd...)
e.checkNextLine(t, "3 out of 4 multisig contract") e.checkNextLine(t, "3 out of 4 multisig contract")
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
@ -363,7 +363,7 @@ func TestDumpKeys(t *testing.T) {
e.checkEOF(t) e.checkEOF(t)
}) })
t.Run("1/1 multisig", func(t *testing.T) { t.Run("1/1 multisig", func(t *testing.T) {
cmd := append(cmd, "--address", "NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF") cmd := append(cmd, "--address", "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP")
e.Run(t, cmd...) e.Run(t, cmd...)
e.checkNextLine(t, "1 out of 1 multisig contract") e.checkNextLine(t, "1 out of 1 multisig contract")
e.checkNextLine(t, pubRegex) e.checkNextLine(t, pubRegex)

View file

@ -1,29 +1,29 @@
{ {
"version": "3.0", "version": "3.0",
"scrypt" : {
"p" : 8,
"r" : 8,
"n" : 16384
},
"accounts": [ "accounts": [
{ {
"isdefault" : false, "address": "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB",
"key": "6PYMKWG2sqfBJ3imGiDyzhiBMviFYgPGQhgehGALkvySJ9kvn4V4FVsceQ",
"label": "my_account",
"contract": { "contract": {
"script": "DCEDhEhWuuSSNuCc7nLsxQhI8nFlt+UfY3oP0/UkYmdH7G5BVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
"type": "Signature" "type": "Signature"
} }
], ],
"script" : "DCEDhEhWuuSSNuCc7nLsxQhI8nFlt+UfY3oP0/UkYmdH7G5BdHR2qg==",
"deployed": false "deployed": false
}, },
"key" : "6PYUz1rNSwDf9ad1vxYbJyK93GrnnPBhr819HgSefMvgU1H9QxqVVCZQtN",
"lock": false, "lock": false,
"label" : "my_account", "isdefault": false
"address" : "NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S"
} }
], ],
"scrypt": {
"n": 16384,
"r": 8,
"p": 8
},
"extra": { "extra": {
"Tokens": null "Tokens": null
} }

View file

@ -35,7 +35,7 @@ var (
// contractOwner is a special address that can perform some management // contractOwner is a special address that can perform some management
// functions on this contract like updating/destroying it and can also // functions on this contract like updating/destroying it and can also
// be used for contract address verification. // be used for contract address verification.
contractOwner = util.FromAddress("NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S") contractOwner = util.FromAddress("NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB")
) )
// Symbol returns token symbol, it's HASHY. // Symbol returns token symbol, it's HASHY.

View file

@ -7,7 +7,7 @@ import (
var ( var (
// Check if the invoker of the contract is the specified owner // Check if the invoker of the contract is the specified owner
owner = util.FromAddress("NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S") owner = util.FromAddress("NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB")
trigger byte trigger byte
) )

View file

@ -16,7 +16,7 @@ var (
// ctx holds storage context for contract methods // ctx holds storage context for contract methods
ctx storage.Context ctx storage.Context
// Check if the invoker of the contract is the specified owner // Check if the invoker of the contract is the specified owner
owner = util.FromAddress("NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S") owner = util.FromAddress("NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB")
// ticksKey is a storage key for ticks counter // ticksKey is a storage key for ticks counter
ticksKey = []byte("ticks") ticksKey = []byte("ticks")
) )

View file

@ -13,7 +13,7 @@ const (
) )
var ( var (
owner = util.FromAddress("NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S") owner = util.FromAddress("NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB")
trigger byte trigger byte
token TokenConfig token TokenConfig
ctx storage.Context ctx storage.Context

View file

@ -13,7 +13,7 @@ const (
) )
var ( var (
owner = util.FromAddress("NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S") owner = util.FromAddress("NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB")
token nep17.Token token nep17.Token
ctx storage.Context ctx storage.Context
) )

View file

@ -14,28 +14,28 @@ type Ktype struct {
// Arr contains a set of known keys in Ktype format. // Arr contains a set of known keys in Ktype format.
var Arr = []Ktype{ var Arr = []Ktype{
{ {
Address: "NQrEVKgpx2qEg6DpVMT5H8kFa7kc2DFgqS", Address: "NPTmAHDxo6Pkyic8Nvu3kwyXoYJCvcCB6i",
PrivateKey: "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344", PrivateKey: "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344",
PublicKey: "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef", PublicKey: "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef",
Wif: "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g", Wif: "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g",
Passphrase: "city of zion", Passphrase: "city of zion",
EncryptedWif: "6PYWaEBMd9UTVFKi1YahYXY5NMLDg9U6w2gpQYUnx8wvaFgdo8EeVPaD7o", EncryptedWif: "6PYUUUFei9PBBfVkSn8q7hFCnewWFRBKPxcn6Kz6Bmk3FqWyLyuTQE2XFH",
}, },
{ {
Address: "NYaVsrMV9GS8aaspRS4odXf1WHZdMmJiPC", Address: "NMBfzaEq2c5zodiNbLPoohVENARMbJim1r",
PrivateKey: "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69", PrivateKey: "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69",
PublicKey: "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9", PublicKey: "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9",
Wif: "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG", Wif: "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG",
Passphrase: "我的密码", Passphrase: "我的密码",
EncryptedWif: "6PYUpn5uxTpsoawM3YKEWamk2oiKeafQBBK3Vutsowogy8a86jPu71xhE9", EncryptedWif: "6PYUmBuLbdXdnybyNeafUJUrVhoBRZpjHACdY9K2VCNzD5tuX5tXgr9fur",
}, },
{ {
Address: "NWcpK2143ZjgzDYyQJhoKrodJUymHTxPzR", Address: "NfVdwyaJbijrWkRagrvs4eSRQUpP7WpukT",
PrivateKey: "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b", PrivateKey: "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b",
PublicKey: "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa", PublicKey: "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
Wif: "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG", Wif: "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
Passphrase: "MyL33tP@33w0rd", Passphrase: "MyL33tP@33w0rd",
EncryptedWif: "6PYRbKt55d4NXxCESqk8n9kURqopvixEY5nhAYe2ZJ4c1oDWAjtFX8hd1M", EncryptedWif: "6PYLQ9oCoEWCfuuHkq6xH4tYbi4Pyv9HYUU8WGkFVXtoczwTbitMjypkma",
}, },
{ {
Address: "NWcpK2143ZjgzDYyQJhoKrodJUymHTxPzR", Address: "NWcpK2143ZjgzDYyQJhoKrodJUymHTxPzR",

View file

@ -88,16 +88,14 @@ func TestSyscallExecution(t *testing.T) {
"storage.GetReadOnlyContext": {interopnames.SystemStorageGetReadOnlyContext, nil, false}, "storage.GetReadOnlyContext": {interopnames.SystemStorageGetReadOnlyContext, nil, false},
"storage.Put": {interopnames.SystemStoragePut, []string{sctx, b, b}, true}, "storage.Put": {interopnames.SystemStoragePut, []string{sctx, b, b}, true},
"storage.ConvertContextToReadOnly": {interopnames.SystemStorageAsReadOnly, []string{sctx}, false}, "storage.ConvertContextToReadOnly": {interopnames.SystemStorageAsReadOnly, []string{sctx}, false},
"crypto.CheckMultisig": {interopnames.NeoCryptoCheckMultisig, []string{pubs, sigs}, false}, "crypto.CheckMultisig": {interopnames.SystemCryptoCheckMultisig, []string{pubs, sigs}, false},
"crypto.CheckSig": {interopnames.NeoCryptoCheckSig, []string{pub, sig}, false}, "crypto.CheckSig": {interopnames.SystemCryptoCheckSig, []string{pub, sig}, false},
} }
ic := &interop.Context{} ic := &interop.Context{}
core.SpawnVM(ic) // set Functions field core.SpawnVM(ic) // set Functions field
for _, fs := range ic.Functions { for _, fs := range ic.Functions {
for i := range fs {
// It will be set in test and we want to fail if calling invalid syscall. // It will be set in test and we want to fail if calling invalid syscall.
fs[i].Func = nil fs.Func = nil
}
} }
for goName, tc := range interops { for goName, tc := range interops {
t.Run(goName, func(t *testing.T) { t.Run(goName, func(t *testing.T) {

View file

@ -19,7 +19,7 @@ func TestVerifyGood(t *testing.T) {
src := getVerifyProg(pub, sig) src := getVerifyProg(pub, sig)
v, p := vmAndCompileInterop(t, src) v, p := vmAndCompileInterop(t, src)
p.interops[interopnames.ToID([]byte(interopnames.NeoCryptoCheckSig))] = func(v *vm.VM) error { p.interops[interopnames.ToID([]byte(interopnames.SystemCryptoCheckSig))] = func(v *vm.VM) error {
assert.Equal(t, pub, v.Estack().Pop().Bytes()) assert.Equal(t, pub, v.Estack().Pop().Bytes())
assert.Equal(t, sig, v.Estack().Pop().Bytes()) assert.Equal(t, sig, v.Estack().Pop().Bytes())
v.Estack().PushVal(true) v.Estack().PushVal(true)

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBdHR2qg==", "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NUREbqw2kfbPgDeEz8Dac2QxntGGqqFMm7", "address": "NMUedC8TSV2rE17wGguSvPk9XcmHSaT275",
"key": "6PYXADog3RQCwKRhqQsobwZEFopdcCJuMfPosM9pXPaDWSguKvznLdpADk", "key": "6PYSYoZaxqDu5vqvm7yUFT3sPJJFwyLyYDnp8zwj1YVPcBWxacz64bNX59",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG5BdHR2qg==", "script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG5BVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYXADog3RQCwKRhqQsobwZEFopdcCJuMfPosM9pXPaDWSguKvznLdpADk", "key": "6PYSYoZaxqDu5vqvm7yUFT3sPJJFwyLyYDnp8zwj1YVPcBWxacz64bNX59",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NQP81vKVRmwZHveX8C9Rbf2qejSpT1W1Eu", "address": "NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo",
"key": "6PYScv3Vgvdi9EkhDNvHXdvQeuaXK9gRwXDmytCswZMNpTzMLvfgR3U5dK", "key": "6PYVxMnzPMFTYY16xRvXm2SJcvaChabLzaARAb1Mmej9U7rYLYWMSPtfam",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5plBdHR2qg==", "script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5plBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYScv3Vgvdi9EkhDNvHXdvQeuaXK9gRwXDmytCswZMNpTzMLvfgR3U5dK", "key": "6PYVxMnzPMFTYY16xRvXm2SJcvaChabLzaARAb1Mmej9U7rYLYWMSPtfam",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NLA34vf8eXGGUhRjVaYe5f8YsyYHTehbDZ", "address": "NPrB7BmTMYxf9UVroJp4RQExM9tqKmsHTz",
"key": "6PYVwp1Sdg9DfTzvg42PZxgzMDf5a5FYBgT6ynKKzwmSHuhGkipoNjyW3a", "key": "6PYX8eELiDduPW3RGiZxZNmG6KtWtXkyRFi47f8w6quEBpRkpBPxH5u5AP",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWJBdHR2qg==", "script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYVwp1Sdg9DfTzvg42PZxgzMDf5a5FYBgT6ynKKzwmSHuhGkipoNjyW3a", "key": "6PYX8eELiDduPW3RGiZxZNmG6KtWtXkyRFi47f8w6quEBpRkpBPxH5u5AP",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -1847,7 +1847,7 @@ func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interop.Context { func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interop.Context {
ic := interop.NewContext(trigger, bc, d, bc.contracts.Management.GetContract, bc.contracts.Contracts, block, tx, bc.log) ic := interop.NewContext(trigger, bc, d, bc.contracts.Management.GetContract, bc.contracts.Contracts, block, tx, bc.log)
ic.Functions = [][]interop.Function{systemInterops, neoInterops} ic.Functions = systemInterops
switch { switch {
case tx != nil: case tx != nil:
ic.Container = tx ic.Container = tx

View file

@ -269,7 +269,7 @@ func TestCreateBasicChain(t *testing.T) {
require.NoError(t, acc0.SignTx(testchain.Network(), txSendRaw)) require.NoError(t, acc0.SignTx(testchain.Network(), txSendRaw))
bw := io.NewBufBinWriter() bw := io.NewBufBinWriter()
txSendRaw.EncodeBinary(bw.BinWriter) txSendRaw.EncodeBinary(bw.BinWriter)
t.Logf("sendrawtransaction: %s", base64.StdEncoding.EncodeToString(bw.Bytes())) t.Logf("sendrawtransaction: \n\tbase64: %s\n\tHash LE: %s", base64.StdEncoding.EncodeToString(bw.Bytes()), txSendRaw.Hash().StringLE())
require.False(t, saveChain) require.False(t, saveChain)
} }

View file

@ -44,7 +44,7 @@ type Context struct {
Notifications []state.NotificationEvent Notifications []state.NotificationEvent
Log *zap.Logger Log *zap.Logger
VM *vm.VM VM *vm.VM
Functions [][]Function Functions []Function
getContract func(dao.DAO, util.Uint160) (*state.Contract, error) getContract func(dao.DAO, util.Uint160) (*state.Contract, error)
} }
@ -64,8 +64,8 @@ func NewContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO,
DAO: dao, DAO: dao,
Notifications: nes, Notifications: nes,
Log: log, Log: log,
// Functions is a slice of slices of interops sorted by ID. // Functions is a slice of interops sorted by ID.
Functions: [][]Function{}, Functions: []Function{},
getContract: getContract, getContract: getContract,
} }
} }
@ -229,13 +229,11 @@ func (ic *Context) GetContract(hash util.Uint160) (*state.Contract, error) {
// GetFunction returns metadata for interop with the specified id. // GetFunction returns metadata for interop with the specified id.
func (ic *Context) GetFunction(id uint32) *Function { func (ic *Context) GetFunction(id uint32) *Function {
for _, slice := range ic.Functions { n := sort.Search(len(ic.Functions), func(i int) bool {
n := sort.Search(len(slice), func(i int) bool { return ic.Functions[i].ID >= id
return slice[i].ID >= id
}) })
if n < len(slice) && slice[n].ID == id { if n < len(ic.Functions) && ic.Functions[n].ID == id {
return &slice[n] return &ic.Functions[n]
}
} }
return nil return nil
} }

View file

@ -71,8 +71,8 @@ func initCheckMultisigVMNoArgs(container *transaction.Transaction) *vm.VM {
Network: uint32(netmode.UnitTestNet), Network: uint32(netmode.UnitTestNet),
Trigger: trigger.Verification, Trigger: trigger.Verification,
Container: container, Container: container,
Functions: Interops,
} }
Register(ic)
v := ic.SpawnVM() v := ic.SpawnVM()
v.LoadScript(buf) v.LoadScript(buf)
return v return v

View file

@ -6,20 +6,16 @@ import (
) )
var ( var (
neoCryptoCheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisig)) neoCryptoCheckMultisigID = interopnames.ToID([]byte(interopnames.SystemCryptoCheckMultisig))
neoCryptoCheckSigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckSig)) neoCryptoCheckSigID = interopnames.ToID([]byte(interopnames.SystemCryptoCheckSig))
) )
var cryptoInterops = []interop.Function{ // Interops represents sorted crypto-related interop functions.
var Interops = []interop.Function{
{ID: neoCryptoCheckMultisigID, Func: ECDSASecp256r1CheckMultisig}, {ID: neoCryptoCheckMultisigID, Func: ECDSASecp256r1CheckMultisig},
{ID: neoCryptoCheckSigID, Func: ECDSASecp256r1CheckSig}, {ID: neoCryptoCheckSigID, Func: ECDSASecp256r1CheckSig},
} }
func init() { func init() {
interop.Sort(cryptoInterops) interop.Sort(Interops)
}
// Register adds crypto interops to ic.
func Register(ic *interop.Context) {
ic.Functions = append(ic.Functions, cryptoInterops)
} }

View file

@ -13,6 +13,8 @@ const (
SystemContractGetCallFlags = "System.Contract.GetCallFlags" SystemContractGetCallFlags = "System.Contract.GetCallFlags"
SystemContractNativeOnPersist = "System.Contract.NativeOnPersist" SystemContractNativeOnPersist = "System.Contract.NativeOnPersist"
SystemContractNativePostPersist = "System.Contract.NativePostPersist" SystemContractNativePostPersist = "System.Contract.NativePostPersist"
SystemCryptoCheckSig = "System.Crypto.CheckSig"
SystemCryptoCheckMultisig = "System.Crypto.CheckMultisig"
SystemIteratorNext = "System.Iterator.Next" SystemIteratorNext = "System.Iterator.Next"
SystemIteratorValue = "System.Iterator.Value" SystemIteratorValue = "System.Iterator.Value"
SystemRuntimeBurnGas = "System.Runtime.BurnGas" SystemRuntimeBurnGas = "System.Runtime.BurnGas"
@ -36,8 +38,6 @@ const (
SystemStorageGetReadOnlyContext = "System.Storage.GetReadOnlyContext" SystemStorageGetReadOnlyContext = "System.Storage.GetReadOnlyContext"
SystemStoragePut = "System.Storage.Put" SystemStoragePut = "System.Storage.Put"
SystemStorageAsReadOnly = "System.Storage.AsReadOnly" SystemStorageAsReadOnly = "System.Storage.AsReadOnly"
NeoCryptoCheckMultisig = "Neo.Crypto.CheckMultisig"
NeoCryptoCheckSig = "Neo.Crypto.CheckSig"
) )
var names = []string{ var names = []string{
@ -75,6 +75,6 @@ var names = []string{
SystemStorageGetReadOnlyContext, SystemStorageGetReadOnlyContext,
SystemStoragePut, SystemStoragePut,
SystemStorageAsReadOnly, SystemStorageAsReadOnly,
NeoCryptoCheckMultisig, SystemCryptoCheckMultisig,
NeoCryptoCheckSig, SystemCryptoCheckSig,
} }

View file

@ -1,66 +0,0 @@
package core
import (
"bytes"
"errors"
"fmt"
"sort"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
var (
errGasLimitExceeded = errors.New("gas limit exceeded")
errFindInvalidOptions = errors.New("invalid Find options")
)
// storageFind finds stored key-value pair.
func storageFind(ic *interop.Context) error {
stcInterface := ic.VM.Estack().Pop().Value()
stc, ok := stcInterface.(*StorageContext)
if !ok {
return fmt.Errorf("%T is not a StorageContext", stcInterface)
}
prefix := ic.VM.Estack().Pop().Bytes()
opts := ic.VM.Estack().Pop().BigInt().Int64()
if opts&^storage.FindAll != 0 {
return fmt.Errorf("%w: unknown flag", errFindInvalidOptions)
}
if opts&storage.FindKeysOnly != 0 &&
opts&(storage.FindDeserialize|storage.FindPick0|storage.FindPick1) != 0 {
return fmt.Errorf("%w KeysOnly conflicts with other options", errFindInvalidOptions)
}
if opts&storage.FindValuesOnly != 0 &&
opts&(storage.FindKeysOnly|storage.FindRemovePrefix) != 0 {
return fmt.Errorf("%w: KeysOnly conflicts with ValuesOnly", errFindInvalidOptions)
}
if opts&storage.FindPick0 != 0 && opts&storage.FindPick1 != 0 {
return fmt.Errorf("%w: Pick0 conflicts with Pick1", errFindInvalidOptions)
}
if opts&storage.FindDeserialize == 0 && (opts&storage.FindPick0 != 0 || opts&storage.FindPick1 != 0) {
return fmt.Errorf("%w: PickN is specified without Deserialize", errFindInvalidOptions)
}
siMap, err := ic.DAO.GetStorageItemsWithPrefix(stc.ID, prefix)
if err != nil {
return err
}
filteredMap := stackitem.NewMap()
for k, v := range siMap {
key := append(prefix, []byte(k)...)
keycopy := make([]byte, len(key))
copy(keycopy, key)
filteredMap.Add(stackitem.NewByteArray(keycopy), stackitem.NewByteArray(v))
}
sort.Slice(filteredMap.Value().([]stackitem.MapElement), func(i, j int) bool {
return bytes.Compare(filteredMap.Value().([]stackitem.MapElement)[i].Key.Value().([]byte),
filteredMap.Value().([]stackitem.MapElement)[j].Key.Value().([]byte)) == -1
})
item := storage.NewIterator(filteredMap, len(prefix), opts)
ic.VM.Estack().PushVal(stackitem.NewInterop(item))
return nil
}

View file

@ -1,280 +0,0 @@
package core
import (
"math/big"
"testing"
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require"
)
/* Missing tests:
* TestTxGetWitnesses
* TestAccountIsStandard
* TestCreateContractStateFromVM
* TestContractCreate
* TestContractMigrate
* TestRuntimeSerialize
* TestRuntimeDeserialize
*/
func TestStorageFind(t *testing.T) {
v, contractState, context, chain := createVMAndContractState(t)
arr := []stackitem.Item{
stackitem.NewBigInteger(big.NewInt(42)),
stackitem.NewByteArray([]byte("second")),
stackitem.Null{},
}
rawArr, err := stackitem.SerializeItem(stackitem.NewArray(arr))
require.NoError(t, err)
rawArr0, err := stackitem.SerializeItem(stackitem.NewArray(arr[:0]))
require.NoError(t, err)
rawArr1, err := stackitem.SerializeItem(stackitem.NewArray(arr[:1]))
require.NoError(t, err)
skeys := [][]byte{{0x01, 0x02}, {0x02, 0x01}, {0x01, 0x01},
{0x04, 0x00}, {0x05, 0x00}, {0x06}, {0x07}, {0x08},
{0x09, 0x12, 0x34}, {0x09, 0x12, 0x56},
}
items := []state.StorageItem{
[]byte{0x01, 0x02, 0x03, 0x04},
[]byte{0x04, 0x03, 0x02, 0x01},
[]byte{0x03, 0x04, 0x05, 0x06},
[]byte{byte(stackitem.ByteArrayT), 2, 0xCA, 0xFE},
[]byte{0xFF, 0xFF},
rawArr,
rawArr0,
rawArr1,
[]byte{111},
[]byte{222},
}
require.NoError(t, chain.contracts.Management.PutContractState(chain.dao, contractState))
id := contractState.ID
for i := range skeys {
err := context.DAO.PutStorageItem(id, skeys[i], items[i])
require.NoError(t, err)
}
testFind := func(t *testing.T, prefix []byte, opts int64, expected []stackitem.Item) {
v.Estack().PushVal(opts)
v.Estack().PushVal(prefix)
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: id}))
err := storageFind(context)
require.NoError(t, err)
var iter *stackitem.Interop
require.NotPanics(t, func() { iter = v.Estack().Pop().Interop() })
for i := range expected { // sorted indices with mathing prefix
v.Estack().PushVal(iter)
require.NoError(t, iterator.Next(context))
require.True(t, v.Estack().Pop().Bool())
v.Estack().PushVal(iter)
if expected[i] == nil {
require.Panics(t, func() { _ = iterator.Value(context) })
return
}
require.NoError(t, iterator.Value(context))
require.Equal(t, expected[i], v.Estack().Pop().Item())
}
v.Estack().PushVal(iter)
require.NoError(t, iterator.Next(context))
require.False(t, v.Estack().Pop().Bool())
}
t.Run("normal invocation", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindDefault, []stackitem.Item{
stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray(skeys[2]),
stackitem.NewByteArray(items[2]),
}),
stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray(skeys[0]),
stackitem.NewByteArray(items[0]),
}),
})
})
t.Run("keys only", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindKeysOnly, []stackitem.Item{
stackitem.NewByteArray(skeys[2]),
stackitem.NewByteArray(skeys[0]),
})
})
t.Run("remove prefix", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindKeysOnly|istorage.FindRemovePrefix, []stackitem.Item{
stackitem.NewByteArray(skeys[2][1:]),
stackitem.NewByteArray(skeys[0][1:]),
})
testFind(t, []byte{0x09, 0x12}, istorage.FindKeysOnly|istorage.FindRemovePrefix, []stackitem.Item{
stackitem.NewByteArray(skeys[8][2:]),
stackitem.NewByteArray(skeys[9][2:]),
})
})
t.Run("values only", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindValuesOnly, []stackitem.Item{
stackitem.NewByteArray(items[2]),
stackitem.NewByteArray(items[0]),
})
})
t.Run("deserialize values", func(t *testing.T) {
testFind(t, []byte{0x04}, istorage.FindValuesOnly|istorage.FindDeserialize, []stackitem.Item{
stackitem.NewByteArray(items[3][2:]),
})
t.Run("invalid", func(t *testing.T) {
v.Estack().PushVal(istorage.FindDeserialize)
v.Estack().PushVal([]byte{0x05})
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: id}))
err := storageFind(context)
require.NoError(t, err)
var iter *stackitem.Interop
require.NotPanics(t, func() { iter = v.Estack().Pop().Interop() })
v.Estack().PushVal(iter)
require.NoError(t, iterator.Next(context))
v.Estack().PushVal(iter)
require.Panics(t, func() { _ = iterator.Value(context) })
})
})
t.Run("PickN", func(t *testing.T) {
testFind(t, []byte{0x06}, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize, arr[:1])
testFind(t, []byte{0x06}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize, arr[1:2])
// Array with 0 elements.
testFind(t, []byte{0x07}, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize,
[]stackitem.Item{nil})
// Array with 1 element.
testFind(t, []byte{0x08}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
[]stackitem.Item{nil})
// Not an array, but serialized ByteArray.
testFind(t, []byte{0x04}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
[]stackitem.Item{nil})
})
t.Run("normal invocation, empty result", func(t *testing.T) {
testFind(t, []byte{0x03}, istorage.FindDefault, nil)
})
t.Run("invalid options", func(t *testing.T) {
invalid := []int64{
istorage.FindKeysOnly | istorage.FindValuesOnly,
^istorage.FindAll,
istorage.FindKeysOnly | istorage.FindDeserialize,
istorage.FindPick0,
istorage.FindPick0 | istorage.FindPick1 | istorage.FindDeserialize,
istorage.FindPick0 | istorage.FindPick1,
}
for _, opts := range invalid {
v.Estack().PushVal(opts)
v.Estack().PushVal([]byte{0x01})
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: id}))
require.Error(t, storageFind(context))
}
})
t.Run("invalid type for StorageContext", func(t *testing.T) {
v.Estack().PushVal(istorage.FindDefault)
v.Estack().PushVal([]byte{0x01})
v.Estack().PushVal(stackitem.NewInterop(nil))
require.Error(t, storageFind(context))
})
t.Run("invalid id", func(t *testing.T) {
invalidID := id + 1
v.Estack().PushVal(istorage.FindDefault)
v.Estack().PushVal([]byte{0x01})
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: invalidID}))
require.NoError(t, storageFind(context))
require.NoError(t, iterator.Next(context))
require.False(t, v.Estack().Pop().Bool())
})
}
// Helper functions to create VM, InteropContext, TX, Account, Contract.
func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
chain := newTestChain(t)
context := chain.newInteropContext(trigger.Application,
dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader), nil, nil)
v := context.SpawnVM()
return v, context, chain
}
func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Blockchain) {
v, block, context, chain := createVMAndBlock(t)
v.Estack().PushVal(stackitem.NewInterop(block))
return v, block, context, chain
}
func createVMAndBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Blockchain) {
block := newDumbBlock()
chain := newTestChain(t)
d := dao.NewSimple(storage.NewMemoryStore(), chain.GetConfig().StateRootInHeader)
context := chain.newInteropContext(trigger.Application, d, block, nil)
v := context.SpawnVM()
return v, block, context, chain
}
func createVMAndPushTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
v, tx, context, chain := createVMAndTX(t)
v.Estack().PushVal(stackitem.NewInterop(tx))
return v, tx, context, chain
}
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
script := []byte("testscript")
m := manifest.NewManifest("Test")
ne, err := nef.NewFile(script)
require.NoError(t, err)
contractState := &state.Contract{
ContractBase: state.ContractBase{
NEF: *ne,
Hash: hash.Hash160(script),
Manifest: *m,
ID: 123,
},
}
chain := newTestChain(t)
d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader)
context := chain.newInteropContext(trigger.Application, d, nil, nil)
v := context.SpawnVM()
return v, contractState, context, chain
}
func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
tx := transaction.New(script, 0)
tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3, 4}}}
tx.Scripts = []transaction.Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}}
chain := newTestChain(t)
d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader)
context := chain.newInteropContext(trigger.Application, d, nil, tx)
v := context.SpawnVM()
return v, tx, context, chain
}

View file

@ -1,13 +1,16 @@
package core package core
import ( import (
"bytes"
"crypto/elliptic" "crypto/elliptic"
"errors" "errors"
"fmt" "fmt"
"math" "math"
"sort"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -17,6 +20,11 @@ import (
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
var (
errGasLimitExceeded = errors.New("gas limit exceeded")
errFindInvalidOptions = errors.New("invalid Find options")
)
// StorageContext contains storing id and read/write flag, it's used as // StorageContext contains storing id and read/write flag, it's used as
// a context for storage manipulation functions. // a context for storage manipulation functions.
type StorageContext struct { type StorageContext struct {
@ -153,6 +161,55 @@ func storageContextAsReadOnly(ic *interop.Context) error {
return nil return nil
} }
// storageFind finds stored key-value pair.
func storageFind(ic *interop.Context) error {
stcInterface := ic.VM.Estack().Pop().Value()
stc, ok := stcInterface.(*StorageContext)
if !ok {
return fmt.Errorf("%T is not a StorageContext", stcInterface)
}
prefix := ic.VM.Estack().Pop().Bytes()
opts := ic.VM.Estack().Pop().BigInt().Int64()
if opts&^istorage.FindAll != 0 {
return fmt.Errorf("%w: unknown flag", errFindInvalidOptions)
}
if opts&istorage.FindKeysOnly != 0 &&
opts&(istorage.FindDeserialize|istorage.FindPick0|istorage.FindPick1) != 0 {
return fmt.Errorf("%w KeysOnly conflicts with other options", errFindInvalidOptions)
}
if opts&istorage.FindValuesOnly != 0 &&
opts&(istorage.FindKeysOnly|istorage.FindRemovePrefix) != 0 {
return fmt.Errorf("%w: KeysOnly conflicts with ValuesOnly", errFindInvalidOptions)
}
if opts&istorage.FindPick0 != 0 && opts&istorage.FindPick1 != 0 {
return fmt.Errorf("%w: Pick0 conflicts with Pick1", errFindInvalidOptions)
}
if opts&istorage.FindDeserialize == 0 && (opts&istorage.FindPick0 != 0 || opts&istorage.FindPick1 != 0) {
return fmt.Errorf("%w: PickN is specified without Deserialize", errFindInvalidOptions)
}
siMap, err := ic.DAO.GetStorageItemsWithPrefix(stc.ID, prefix)
if err != nil {
return err
}
filteredMap := stackitem.NewMap()
for k, v := range siMap {
key := append(prefix, []byte(k)...)
keycopy := make([]byte, len(key))
copy(keycopy, key)
filteredMap.Add(stackitem.NewByteArray(keycopy), stackitem.NewByteArray(v))
}
sort.Slice(filteredMap.Value().([]stackitem.MapElement), func(i, j int) bool {
return bytes.Compare(filteredMap.Value().([]stackitem.MapElement)[i].Key.Value().([]byte),
filteredMap.Value().([]stackitem.MapElement)[j].Key.Value().([]byte)) == -1
})
item := istorage.NewIterator(filteredMap, len(prefix), opts)
ic.VM.Estack().PushVal(stackitem.NewInterop(item))
return nil
}
// contractCreateMultisigAccount calculates multisig contract scripthash for a // contractCreateMultisigAccount calculates multisig contract scripthash for a
// given m and a set of public keys. // given m and a set of public keys.
func contractCreateMultisigAccount(ic *interop.Context) error { func contractCreateMultisigAccount(ic *interop.Context) error {

View file

@ -7,10 +7,14 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/internal/random" "github.com/nspcc-dev/neo-go/internal/random"
"github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/interop/contract" "github.com/nspcc-dev/neo-go/pkg/core/interop/contract"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime" "github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
istorage "github.com/nspcc-dev/neo-go/pkg/core/interop/storage"
"github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
@ -22,6 +26,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
@ -254,6 +259,252 @@ func TestStorageDelete(t *testing.T) {
}) })
} }
func TestStorageFind(t *testing.T) {
v, contractState, context, chain := createVMAndContractState(t)
arr := []stackitem.Item{
stackitem.NewBigInteger(big.NewInt(42)),
stackitem.NewByteArray([]byte("second")),
stackitem.Null{},
}
rawArr, err := stackitem.SerializeItem(stackitem.NewArray(arr))
require.NoError(t, err)
rawArr0, err := stackitem.SerializeItem(stackitem.NewArray(arr[:0]))
require.NoError(t, err)
rawArr1, err := stackitem.SerializeItem(stackitem.NewArray(arr[:1]))
require.NoError(t, err)
skeys := [][]byte{{0x01, 0x02}, {0x02, 0x01}, {0x01, 0x01},
{0x04, 0x00}, {0x05, 0x00}, {0x06}, {0x07}, {0x08},
{0x09, 0x12, 0x34}, {0x09, 0x12, 0x56},
}
items := []state.StorageItem{
[]byte{0x01, 0x02, 0x03, 0x04},
[]byte{0x04, 0x03, 0x02, 0x01},
[]byte{0x03, 0x04, 0x05, 0x06},
[]byte{byte(stackitem.ByteArrayT), 2, 0xCA, 0xFE},
[]byte{0xFF, 0xFF},
rawArr,
rawArr0,
rawArr1,
[]byte{111},
[]byte{222},
}
require.NoError(t, chain.contracts.Management.PutContractState(chain.dao, contractState))
id := contractState.ID
for i := range skeys {
err := context.DAO.PutStorageItem(id, skeys[i], items[i])
require.NoError(t, err)
}
testFind := func(t *testing.T, prefix []byte, opts int64, expected []stackitem.Item) {
v.Estack().PushVal(opts)
v.Estack().PushVal(prefix)
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: id}))
err := storageFind(context)
require.NoError(t, err)
var iter *stackitem.Interop
require.NotPanics(t, func() { iter = v.Estack().Pop().Interop() })
for i := range expected { // sorted indices with mathing prefix
v.Estack().PushVal(iter)
require.NoError(t, iterator.Next(context))
require.True(t, v.Estack().Pop().Bool())
v.Estack().PushVal(iter)
if expected[i] == nil {
require.Panics(t, func() { _ = iterator.Value(context) })
return
}
require.NoError(t, iterator.Value(context))
require.Equal(t, expected[i], v.Estack().Pop().Item())
}
v.Estack().PushVal(iter)
require.NoError(t, iterator.Next(context))
require.False(t, v.Estack().Pop().Bool())
}
t.Run("normal invocation", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindDefault, []stackitem.Item{
stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray(skeys[2]),
stackitem.NewByteArray(items[2]),
}),
stackitem.NewStruct([]stackitem.Item{
stackitem.NewByteArray(skeys[0]),
stackitem.NewByteArray(items[0]),
}),
})
})
t.Run("keys only", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindKeysOnly, []stackitem.Item{
stackitem.NewByteArray(skeys[2]),
stackitem.NewByteArray(skeys[0]),
})
})
t.Run("remove prefix", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindKeysOnly|istorage.FindRemovePrefix, []stackitem.Item{
stackitem.NewByteArray(skeys[2][1:]),
stackitem.NewByteArray(skeys[0][1:]),
})
testFind(t, []byte{0x09, 0x12}, istorage.FindKeysOnly|istorage.FindRemovePrefix, []stackitem.Item{
stackitem.NewByteArray(skeys[8][2:]),
stackitem.NewByteArray(skeys[9][2:]),
})
})
t.Run("values only", func(t *testing.T) {
testFind(t, []byte{0x01}, istorage.FindValuesOnly, []stackitem.Item{
stackitem.NewByteArray(items[2]),
stackitem.NewByteArray(items[0]),
})
})
t.Run("deserialize values", func(t *testing.T) {
testFind(t, []byte{0x04}, istorage.FindValuesOnly|istorage.FindDeserialize, []stackitem.Item{
stackitem.NewByteArray(items[3][2:]),
})
t.Run("invalid", func(t *testing.T) {
v.Estack().PushVal(istorage.FindDeserialize)
v.Estack().PushVal([]byte{0x05})
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: id}))
err := storageFind(context)
require.NoError(t, err)
var iter *stackitem.Interop
require.NotPanics(t, func() { iter = v.Estack().Pop().Interop() })
v.Estack().PushVal(iter)
require.NoError(t, iterator.Next(context))
v.Estack().PushVal(iter)
require.Panics(t, func() { _ = iterator.Value(context) })
})
})
t.Run("PickN", func(t *testing.T) {
testFind(t, []byte{0x06}, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize, arr[:1])
testFind(t, []byte{0x06}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize, arr[1:2])
// Array with 0 elements.
testFind(t, []byte{0x07}, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize,
[]stackitem.Item{nil})
// Array with 1 element.
testFind(t, []byte{0x08}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
[]stackitem.Item{nil})
// Not an array, but serialized ByteArray.
testFind(t, []byte{0x04}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
[]stackitem.Item{nil})
})
t.Run("normal invocation, empty result", func(t *testing.T) {
testFind(t, []byte{0x03}, istorage.FindDefault, nil)
})
t.Run("invalid options", func(t *testing.T) {
invalid := []int64{
istorage.FindKeysOnly | istorage.FindValuesOnly,
^istorage.FindAll,
istorage.FindKeysOnly | istorage.FindDeserialize,
istorage.FindPick0,
istorage.FindPick0 | istorage.FindPick1 | istorage.FindDeserialize,
istorage.FindPick0 | istorage.FindPick1,
}
for _, opts := range invalid {
v.Estack().PushVal(opts)
v.Estack().PushVal([]byte{0x01})
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: id}))
require.Error(t, storageFind(context))
}
})
t.Run("invalid type for StorageContext", func(t *testing.T) {
v.Estack().PushVal(istorage.FindDefault)
v.Estack().PushVal([]byte{0x01})
v.Estack().PushVal(stackitem.NewInterop(nil))
require.Error(t, storageFind(context))
})
t.Run("invalid id", func(t *testing.T) {
invalidID := id + 1
v.Estack().PushVal(istorage.FindDefault)
v.Estack().PushVal([]byte{0x01})
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: invalidID}))
require.NoError(t, storageFind(context))
require.NoError(t, iterator.Next(context))
require.False(t, v.Estack().Pop().Bool())
})
}
// Helper functions to create VM, InteropContext, TX, Account, Contract.
func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
chain := newTestChain(t)
context := chain.newInteropContext(trigger.Application,
dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader), nil, nil)
v := context.SpawnVM()
return v, context, chain
}
func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Blockchain) {
v, block, context, chain := createVMAndBlock(t)
v.Estack().PushVal(stackitem.NewInterop(block))
return v, block, context, chain
}
func createVMAndBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Blockchain) {
block := newDumbBlock()
chain := newTestChain(t)
d := dao.NewSimple(storage.NewMemoryStore(), chain.GetConfig().StateRootInHeader)
context := chain.newInteropContext(trigger.Application, d, block, nil)
v := context.SpawnVM()
return v, block, context, chain
}
func createVMAndPushTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
v, tx, context, chain := createVMAndTX(t)
v.Estack().PushVal(stackitem.NewInterop(tx))
return v, tx, context, chain
}
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
script := []byte("testscript")
m := manifest.NewManifest("Test")
ne, err := nef.NewFile(script)
require.NoError(t, err)
contractState := &state.Contract{
ContractBase: state.ContractBase{
NEF: *ne,
Hash: hash.Hash160(script),
Manifest: *m,
ID: 123,
},
}
chain := newTestChain(t)
d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader)
context := chain.newInteropContext(trigger.Application, d, nil, nil)
v := context.SpawnVM()
return v, contractState, context, chain
}
func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
tx := transaction.New(script, 0)
tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3, 4}}}
tx.Scripts = []transaction.Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}}
chain := newTestChain(t)
d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader)
context := chain.newInteropContext(trigger.Application, d, nil, tx)
v := context.SpawnVM()
return v, tx, context, chain
}
// getTestContractState returns 2 contracts second of which is allowed to call the first. // getTestContractState returns 2 contracts second of which is allowed to call the first.
func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) { func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
mgmtHash := bc.ManagementContractHash() mgmtHash := bc.ManagementContractHash()

View file

@ -24,7 +24,7 @@ import (
// up for current blockchain. // up for current blockchain.
func SpawnVM(ic *interop.Context) *vm.VM { func SpawnVM(ic *interop.Context) *vm.VM {
vm := ic.SpawnVM() vm := ic.SpawnVM()
ic.Functions = [][]interop.Function{systemInterops, neoInterops} ic.Functions = systemInterops
return vm return vm
} }
@ -38,6 +38,8 @@ var systemInterops = []interop.Function{
{Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10}, {Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10},
{Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.States}, {Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.States},
{Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, Price: 0, RequiredFlags: callflag.States}, {Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, Price: 0, RequiredFlags: callflag.States},
{Name: interopnames.SystemCryptoCheckMultisig, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 2},
{Name: interopnames.SystemCryptoCheckSig, Func: crypto.ECDSASecp256r1CheckSig, Price: fee.ECDSAVerifyPrice, ParamCount: 2},
{Name: interopnames.SystemIteratorNext, Func: iterator.Next, Price: 1 << 15, ParamCount: 1}, {Name: interopnames.SystemIteratorNext, Func: iterator.Next, Price: 1 << 15, ParamCount: 1},
{Name: interopnames.SystemIteratorValue, Func: iterator.Value, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemIteratorValue, Func: iterator.Value, Price: 1 << 4, ParamCount: 1},
{Name: interopnames.SystemRuntimeBurnGas, Func: runtime.BurnGas, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemRuntimeBurnGas, Func: runtime.BurnGas, Price: 1 << 4, ParamCount: 1},
@ -73,22 +75,10 @@ var systemInterops = []interop.Function{
RequiredFlags: callflag.ReadStates, ParamCount: 1}, RequiredFlags: callflag.ReadStates, ParamCount: 1},
} }
var neoInterops = []interop.Function{
{Name: interopnames.NeoCryptoCheckMultisig, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 2},
{Name: interopnames.NeoCryptoCheckSig, Func: crypto.ECDSASecp256r1CheckSig, Price: fee.ECDSAVerifyPrice, ParamCount: 2},
}
// initIDinInteropsSlice initializes IDs from names in one given
// Function slice and then sorts it.
func initIDinInteropsSlice(iops []interop.Function) {
for i := range iops {
iops[i].ID = interopnames.ToID([]byte(iops[i].Name))
}
interop.Sort(iops)
}
// init initializes IDs in the global interop slices. // init initializes IDs in the global interop slices.
func init() { func init() {
initIDinInteropsSlice(systemInterops) for i := range systemInterops {
initIDinInteropsSlice(neoInterops) systemInterops[i].ID = interopnames.ToID([]byte(systemInterops[i].Name))
}
interop.Sort(systemInterops)
} }

View file

@ -17,14 +17,14 @@ func TestGenesisBlockMainNet(t *testing.T) {
block, err := createGenesisBlock(cfg.ProtocolConfiguration) block, err := createGenesisBlock(cfg.ProtocolConfiguration)
require.NoError(t, err) require.NoError(t, err)
expect := "5816ac116af288777c4c454425fb687981f508826ec474810ff9e6b24202fd9a" expect := "c3db4ba50ede4f9e749bd97e1499953ae17e65a415c6bf9e38c01cf92b03d156"
assert.Equal(t, expect, block.Hash().StringLE()) assert.Equal(t, expect, block.Hash().StringLE())
} }
func TestGetConsensusAddressMainNet(t *testing.T) { func TestGetConsensusAddressMainNet(t *testing.T) {
var ( var (
consensusAddr = "NSX179gdoQmF8nu34rQdL4dYAfdCQhHtQS" consensusAddr = "NVg7LjGcUSrgxgjX3zEgqaksfMaiS8Z6e1"
consensusScript = "4870eaa62eee7c76b76d2ae933d4c027f5f5c77d" consensusScript = "6b123dd8bec718648852bbc78595e3536a058f9f"
) )
cfg, err := config.Load("../../config", netmode.MainNet) cfg, err := config.Load("../../config", netmode.MainNet)

View file

@ -316,7 +316,7 @@ func (p *PublicKey) GetVerificationScript() []byte {
return buf.Bytes() return buf.Bytes()
} }
emit.Bytes(buf.BinWriter, b) emit.Bytes(buf.BinWriter, b)
emit.Syscall(buf.BinWriter, interopnames.NeoCryptoCheckSig) emit.Syscall(buf.BinWriter, interopnames.SystemCryptoCheckSig)
return buf.Bytes() return buf.Bytes()
} }

View file

@ -111,7 +111,7 @@ func TestPubkeyToAddress(t *testing.T) {
pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4") pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
require.NoError(t, err) require.NoError(t, err)
actual := pubKey.Address() actual := pubKey.Address()
expected := "NWmVWWvFA6RxvTs4kgY1NnwTXeLYwWxPb1" expected := "NdxG5MZQy8h2qseawfSt8tTYG2iQPTwsn9"
require.Equal(t, expected, actual) require.Equal(t, expected, actual)
} }

View file

@ -9,14 +9,14 @@ import (
) )
// CheckMultisig checks that script container (transaction) is signed by multiple // CheckMultisig checks that script container (transaction) is signed by multiple
// ECDSA keys at once. It uses `Neo.Crypto.CheckMultisig` syscall. // ECDSA keys at once. It uses `System.Crypto.CheckMultisig` syscall.
func CheckMultisig(pubs []interop.PublicKey, sigs []interop.Signature) bool { func CheckMultisig(pubs []interop.PublicKey, sigs []interop.Signature) bool {
return neogointernal.Syscall2("Neo.Crypto.CheckMultisig", pubs, sigs).(bool) return neogointernal.Syscall2("System.Crypto.CheckMultisig", pubs, sigs).(bool)
} }
// CheckSig checks that sig is correct signature of the script container // CheckSig checks that sig is correct signature of the script container
// (transaction) for a given pub (serialized public key). It uses // (transaction) for a given pub (serialized public key). It uses
// `Neo.Crypto.CheckSig` syscall. // `System.Crypto.CheckSig` syscall.
func CheckSig(pub interop.PublicKey, sig interop.Signature) bool { func CheckSig(pub interop.PublicKey, sig interop.Signature) bool {
return neogointernal.Syscall2("Neo.Crypto.CheckSig", pub, sig).(bool) return neogointernal.Syscall2("System.Crypto.CheckSig", pub, sig).(bool)
} }

View file

@ -1185,7 +1185,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
name: "getnep17transfers_invalid_params_error 2", name: "getnep17transfers_invalid_params_error 2",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
var stop uint32 var stop uint32
return c.GetNEP17Transfers("NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", nil, &stop, nil, nil) return c.GetNEP17Transfers("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", nil, &stop, nil, nil)
}, },
}, },
{ {
@ -1193,7 +1193,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
var start uint32 var start uint32
var limit int var limit int
return c.GetNEP17Transfers("NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", &start, nil, &limit, nil) return c.GetNEP17Transfers("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", &start, nil, &limit, nil)
}, },
}, },
{ {
@ -1201,7 +1201,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
var start, stop uint32 var start, stop uint32
var page int var page int
return c.GetNEP17Transfers("NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", &start, &stop, nil, &page) return c.GetNEP17Transfers("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", &start, &stop, nil, &page)
}, },
}, },
{ {

View file

@ -59,13 +59,13 @@ type rpcTestCase struct {
check func(t *testing.T, e *executor, result interface{}) check func(t *testing.T, e *executor, result interface{})
} }
const testContractHash = "c6ca2347bb84b99807221365c900ec069a265e7c" const testContractHash = "63cc6571e990dd3f345f699fc9c2a6e49edb89af"
const deploymentTxHash = "26692315f71f4790263160c0f570828be77c6927493ae6657a6e5a6a09229eb9" const deploymentTxHash = "4450d0047d4b6a20e85176c709df44fae4c63cfa9a698acb11871554b93016df"
const genesisBlockHash = "5b60644c6c6f58faca72c70689d7ed1f40c2e795772bd0de5a88e983ad55080c" const genesisBlockHash = "73fe50b5564d57118296cbab0a78fe7cb11c97b7699d07a9a21fab60e79bb8fc"
const verifyContractHash = "5bb4bac40e961e334ba7bd36d2496010f67e246e" const verifyContractHash = "c50082e0d8364d61ce6933bd24027a3363474dce"
const verifyContractAVM = "VwMAQS1RCDAhcAwUVVQtU+0PVUb61E1umZEoZwIvzl7bMHFoE87bKGnbKJdA" const verifyContractAVM = "VwMAQS1RCDAhcAwU7p6iLCfjS9AUj8QQjgj3To9QSLLbMHFoE87bKGnbKJdA"
const verifyWithArgsContractHash = "59b08e81dcf94f6ddbef5c2d84a4c1a098b9a984" const verifyWithArgsContractHash = "8744ffdd07af8e9f18ab90685c8c2ebfd37c6415"
const verifyWithArgsContractAVM = "VwIDeAwLZ29vZF9zdHJpbmeXJA15FSgJehHbIJciBRHbIHBoQA==" const verifyWithArgsContractAVM = "VwIDeAwLZ29vZF9zdHJpbmeXJA15FSgJehHbIJciBRHbIHBoQA=="
const invokescriptContractAVM = "VwcADBQBDAMOBQYMDQIODw0DDgcJAAAAANswcGhB+CfsjCGqJgQRQAwUDQ8DAgkAAgEDBwMEBQIBAA4GDAnbMHFpQfgn7IwhqiYEEkATQA==" const invokescriptContractAVM = "VwcADBQBDAMOBQYMDQIODw0DDgcJAAAAANswcGhB+CfsjCGqJgQRQAwUDQ8DAgkAAgEDBwMEBQIBAA4GDAnbMHFpQfgn7IwhqiYEEkATQA=="
@ -917,13 +917,13 @@ var rpcTestCases = map[string][]rpcTestCase{
"sendrawtransaction": { "sendrawtransaction": {
{ {
name: "positive", name: "positive",
params: `["ADQSAADA2KcAAAAAABDiEgAAAAAAgBYAAAFVVC1T7Q9VRvrUTW6ZkShnAi/OXgEAYBDAAwDodkgXAAAADBRdSe/t0S4+BgGLRljbEKiXX8gLTgwUVVQtU+0PVUb61E1umZEoZwIvzl4UwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQFCDEA0sZMiszaJ/YkG3ZzyFKbE+qujQif0RrlplXpBc5IMzxyM4sPBwvpfGTtDtY9NI8gzR1lVL/O6nzPJG9m8XKjxKAwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CQXR0dqo="]`, params: `["ADQSAADA2KcAAAAAABDiEgAAAAAAgBYAAAHunqIsJ+NL0BSPxBCOCPdOj1BIsgEAYBDAAwDodkgXAAAADBQRJlu0FyUAQb4E6PokDjj1fB5WmwwU7p6iLCfjS9AUj8QQjgj3To9QSLIUwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQFCDEBRp0p08GFA2rYC/Xrol8DIhXEMfVMbUJEYer1RqZSatmTjUJE9fnZtDGkQEX/zQ7yOhbnIPAZIrllUTuUBskhUKAwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CQVbnsyc="]`,
result: func(e *executor) interface{} { return &result.RelayResult{} }, result: func(e *executor) interface{} { return &result.RelayResult{} },
check: func(t *testing.T, e *executor, inv interface{}) { check: func(t *testing.T, e *executor, inv interface{}) {
res, ok := inv.(*result.RelayResult) res, ok := inv.(*result.RelayResult)
require.True(t, ok) require.True(t, ok)
expectedHash := util.Uint256{0xaf, 0x80, 0x44, 0x52, 0x49, 0xac, 0xa7, 0xa9, 0x47, 0x11, 0x8, 0xac, 0xdb, 0x59, 0x29, 0xb, 0x3d, 0xac, 0xf2, 0xe9, 0xf7, 0xde, 0x45, 0x79, 0x73, 0x66, 0xe9, 0xb0, 0xd4, 0xc5, 0x6b, 0x97} expectedHash := "8ea251d812fbbdecaebfc164fb6afbd78b7db94f7dacb69421cd5d4e364522d2"
assert.Equal(t, expectedHash, res.Hash) assert.Equal(t, expectedHash, res.Hash.StringLE())
}, },
}, },
{ {
@ -1638,7 +1638,7 @@ func checkNep17Balances(t *testing.T, e *executor, acc interface{}) {
}, },
{ {
Asset: e.chain.UtilityTokenHash(), Asset: e.chain.UtilityTokenHash(),
Amount: "67960042780", Amount: "67960000780",
LastUpdated: 14, LastUpdated: 14,
}}, }},
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(), Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),

Binary file not shown.

View file

@ -6,9 +6,9 @@ import (
) )
// Verify is a verification contract method. // Verify is a verification contract method.
// It returns true iff it is signed by NTh9TnZTstvAePEYWDGLLxidBikJE24uTo (id-0 private key from testchain). // It returns true iff it is signed by Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn (id-0 private key from testchain).
func Verify() bool { func Verify() bool {
tx := runtime.GetScriptContainer() tx := runtime.GetScriptContainer()
addr := util.FromAddress("NTh9TnZTstvAePEYWDGLLxidBikJE24uTo") addr := util.FromAddress("Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn")
return util.Equals(string(tx.Sender), string(addr)) return util.Equals(string(tx.Sender), string(addr))
} }

View file

@ -1,65 +1,64 @@
{ {
"version": "3.0",
"accounts": [
{
"address": "Nbruchf1SGfar3sN4cPr1UG1bWqADrN5sh",
"key": "6PYRC8sNNB5rVx96ezh6Eefw8JcdQPRBfHx7hfe251m4bwHQnH2cZbcRk8",
"label": "",
"contract": {
"script": "DCEDm5PmbOfVPmYXTSVW903XnOhhNBTsF9oDlVYusIH/ui1BVuezJw==",
"parameters": [
{
"name": "parameter0",
"type": "Signature"
}
],
"deployed": false
},
"lock": false,
"isdefault": false
},
{
"address": "NiYvEoR2FTD8FmGXtg1WMhkaTS9A6VH7YV",
"key": "6PYMecvacj5qTSB771Q9k4wfqTRK4SXSQhmDsDAxZxBgEVJf4BsnrgrQYS",
"label": "",
"contract": {
"script": "DCEDHRWEIGXHCwUU2Fc7B0qrYPezXR0sfdEduRExyzIKVC9BVuezJw==",
"parameters": [
{
"name": "parameter0",
"type": "Signature"
}
],
"deployed": false
},
"lock": false,
"isdefault": false
},
{
"address": "NcPWfiU7bJkUpBruEQcGRyo91bTWijcUXY",
"key": "6PYWH6sS2JVshBA5ijMAT1CtFbs9LcLuthYoR4eZMD8TyXShD1c2zLsfjC",
"label": "",
"contract": {
"script": "DCECmUfs/gqKHd3AdJm5+Ev6zkubV8pP8DZzgu8+t5WdphJBVuezJw==",
"parameters": [
{
"name": "parameter0",
"type": "Signature"
}
],
"deployed": false
},
"lock": false,
"isdefault": false
}
],
"scrypt": { "scrypt": {
"n": 16384, "n": 16384,
"r": 8, "r": 8,
"p": 8 "p": 8
}, },
"accounts" : [
{
"contract" : {
"parameters" : [
{
"type" : "Signature",
"name" : "parameter0"
}
],
"deployed" : false,
"script" : "DCEDm5PmbOfVPmYXTSVW903XnOhhNBTsF9oDlVYusIH/ui1BdHR2qg=="
},
"label" : "NotaryNode1",
"address" : "NS6vb4uE8wdQfcQbFcRY7yquSbwbVcMSV3",
"isdefault" : false,
"lock" : false,
"key" : "6PYMGBef95jMZJTQcH9ZP5PuecWa2H86HFbdnfe7VQs8uPZ3S6pu4D5NpP"
},
{
"contract" : {
"script" : "DCEDHRWEIGXHCwUU2Fc7B0qrYPezXR0sfdEduRExyzIKVC9BdHR2qg==",
"deployed" : false,
"parameters" : [
{
"name" : "parameter0",
"type" : "Signature"
}
]
},
"label" : "three",
"address" : "NakELwR1i6brB7EmYLc6yPbvk78Qi5Qbpi",
"isdefault" : false,
"lock" : false,
"key" : "6PYLm6kse9FVpKoBbhYYSFHhFUUL2bZYePU95x7Ncknu798WEHYmTuUijR"
},
{
"contract" : {
"parameters" : [
{
"name" : "parameter0",
"type" : "Signature"
}
],
"deployed" : false,
"script" : "DCECmUfs/gqKHd3AdJm5+Ev6zkubV8pP8DZzgu8+t5WdphJBdHR2qg=="
},
"key" : "6PYWBWehojbBn8U2XWcXxuWqPrnp9qwQ5rD3RKQza1iR5ZBCPHXxCQonYm",
"isdefault" : false,
"lock" : false,
"address" : "NLWXE5CMEqJzEVtscF4BoTvSbiBr1FwtBb",
"label" : "four"
}
],
"extra": { "extra": {
"Tokens": null "Tokens": null
},
"version" : "3.0"
} }
}

View file

@ -1,30 +1,30 @@
{ {
"scrypt" : {
"r" : 8,
"p" : 8,
"n" : 16384
},
"version": "3.0", "version": "3.0",
"extra" : {
"Tokens" : null
},
"accounts": [ "accounts": [
{ {
"address" : "NYt1oLCMMvqxnAVMJCSk87kZTP693GxK11", "address": "NaVp3ZxwZWA84DRewRjnBLFstaeBuVMKwR",
"key" : "6PYWejAoqoF4JT5P9N3EcqC5tRC1MXx2gZ1R2WWryjDUH1bMAo3Bd68nCo", "key": "6PYK1JEBNRL1jnqpD2Vct9sa5gjSfU5p42zavZBmWmKWR8oKvS5mPzcvqm",
"lock" : false, "label": "",
"isdefault" : false,
"contract": { "contract": {
"script": "DCECIcKj0GFdv4b1NZrw9X6zLNLWzmNKAxtw6olIMZxpPRRBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
"type": "Signature" "type": "Signature"
} }
], ],
"deployed" : false, "deployed": false
"script" : "DCECIcKj0GFdv4b1NZrw9X6zLNLWzmNKAxtw6olIMZxpPRRBdHR2qg=="
}, },
"label" : "NotaryNode2" "lock": false,
"isdefault": false
}
],
"scrypt": {
"n": 16384,
"r": 8,
"p": 8
},
"extra": {
"Tokens": null
} }
]
} }

View file

@ -1,30 +1,30 @@
{ {
"version": "3.0",
"accounts": [ "accounts": [
{ {
"address" : "NPcxgUcZorwb1njfRGL7JEyc6SsTku42ek", "address": "NLUCkBS5dtk1h5cedgFoVXqeoCW2UiYNrZ",
"key" : "6PYPy72Gnoif27u9Uy5r2sqMwTTYMLRBGwPcJmB1GP1FTPp4U3M9fZVdtg", "key": "6PYVFexrF2CvxJwx3xpoPchHWJpkrcXy5FZjuXckpArgApVm6AEpQwCuKw",
"lock" : false, "label": "",
"isdefault" : false,
"contract": { "contract": {
"script": "DCEDNxK01e1DnGA+TiGU3H4DKUuGliSz89/NuZCbVvA2u0xBVuezJw==",
"parameters": [ "parameters": [
{ {
"type" : "Signature", "name": "parameter0",
"name" : "parameter0" "type": "Signature"
} }
], ],
"script" : "DCEDNxK01e1DnGA+TiGU3H4DKUuGliSz89/NuZCbVvA2u0xBdHR2qg==",
"deployed": false "deployed": false
}, },
"label" : "" "lock": false,
"isdefault": false
} }
], ],
"extra" : {
"Tokens" : null
},
"version" : "3.0",
"scrypt": { "scrypt": {
"n": 16384, "n": 16384,
"p" : 8, "r": 8,
"r" : 8 "p": 8
},
"extra": {
"Tokens": null
} }
} }

View file

@ -1,30 +1,30 @@
{ {
"version": "3.0", "version": "3.0",
"extra" : {
"Tokens" : null
},
"accounts": [ "accounts": [
{ {
"isdefault" : false, "address": "NUkatH1cgvBeQyDwfyEjTqZRgjmXC1d23A",
"key": "6PYNvsB8P7Ge5SHth9Ui9ikgkupTfED1g7Ec39gn2YDuuM4LFgQgG4j4i3",
"label": "", "label": "",
"key" : "6PYTgfwm5kuahFNN391D6p21ivKrHpvr8Wnn1mBpMnavn6PxkK2prSsxye",
"address" : "NhSCnPJdgLdxnQaYHmW9A3WFLT9DiicBfK",
"lock" : false,
"contract": { "contract": {
"script" : "DCEDEXzwIl4Jhvsj98GYIPFFiedeb1QdP8T79uSBSDNsisxBdHR2qg==", "script": "DCEDEXzwIl4Jhvsj98GYIPFFiedeb1QdP8T79uSBSDNsisxBVuezJw==",
"deployed" : false,
"parameters": [ "parameters": [
{ {
"type" : "Signature", "name": "parameter0",
"name" : "parameter0" "type": "Signature"
}
]
} }
],
"deployed": false
},
"lock": false,
"isdefault": false
} }
], ],
"scrypt": { "scrypt": {
"p" : 8,
"n": 16384, "n": 16384,
"r" : 8 "r": 8,
"p": 8
},
"extra": {
"Tokens": null
} }
} }

View file

@ -118,8 +118,7 @@ func TestParameterContext_AddSignatureMultisig(t *testing.T) {
} }
func newTestVM(w *transaction.Witness, tx *transaction.Transaction) *vm.VM { func newTestVM(w *transaction.Witness, tx *transaction.Transaction) *vm.VM {
ic := &interop.Context{Network: uint32(netmode.UnitTestNet), Container: tx} ic := &interop.Context{Network: uint32(netmode.UnitTestNet), Container: tx, Functions: crypto.Interops}
crypto.Register(ic)
v := ic.SpawnVM() v := ic.SpawnVM()
v.LoadScript(w.VerificationScript) v.LoadScript(w.VerificationScript)
v.LoadScript(w.InvocationScript) v.LoadScript(w.InvocationScript)

View file

@ -30,7 +30,7 @@ func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, erro
emit.Bytes(buf.BinWriter, pubKey.Bytes()) emit.Bytes(buf.BinWriter, pubKey.Bytes())
} }
emit.Int(buf.BinWriter, int64(len(publicKeys))) emit.Int(buf.BinWriter, int64(len(publicKeys)))
emit.Syscall(buf.BinWriter, interopnames.NeoCryptoCheckMultisig) emit.Syscall(buf.BinWriter, interopnames.SystemCryptoCheckMultisig)
return buf.Bytes(), nil return buf.Bytes(), nil
} }

View file

@ -33,7 +33,7 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB()))
assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB())) assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB()))
assert.Equal(t, interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisig)), br.ReadU32LE()) assert.Equal(t, interopnames.ToID([]byte(interopnames.SystemCryptoCheckMultisig)), br.ReadU32LE())
} }
func TestCreateDefaultMultiSigRedeemScript(t *testing.T) { func TestCreateDefaultMultiSigRedeemScript(t *testing.T) {

View file

@ -13,8 +13,8 @@ import (
) )
var ( var (
verifyInteropID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckSig)) verifyInteropID = interopnames.ToID([]byte(interopnames.SystemCryptoCheckSig))
multisigInteropID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisig)) multisigInteropID = interopnames.ToID([]byte(interopnames.SystemCryptoCheckMultisig))
) )
func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) { func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) {

View file

@ -113,13 +113,13 @@ func TestAccount_ConvertMultisig(t *testing.T) {
t.Run("1/1 multisig", func(t *testing.T) { t.Run("1/1 multisig", func(t *testing.T) {
pubs := convertPubs(t, hexs[:1]) pubs := convertPubs(t, hexs[:1])
require.NoError(t, a.ConvertMultisig(1, pubs)) require.NoError(t, a.ConvertMultisig(1, pubs))
require.Equal(t, "NNudMSGzEoktFzdYGYoNb3bzHzbmM1genF", a.Address) require.Equal(t, "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", a.Address)
}) })
t.Run("3/4 multisig", func(t *testing.T) { t.Run("3/4 multisig", func(t *testing.T) {
pubs := convertPubs(t, hexs) pubs := convertPubs(t, hexs)
require.NoError(t, a.ConvertMultisig(3, pubs)) require.NoError(t, a.ConvertMultisig(3, pubs))
require.Equal(t, "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", a.Address) require.Equal(t, "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq", a.Address)
}) })
} }

View file

@ -56,13 +56,7 @@ func TestRegenerateSoloWallet(t *testing.T) {
acc3 := getAccount(t, wif, "one") acc3 := getAccount(t, wif, "one")
require.NoError(t, acc3.ConvertMultisig(1, keys.PublicKeys{getKeys(t)[0]})) require.NoError(t, acc3.ConvertMultisig(1, keys.PublicKeys{getKeys(t)[0]}))
w, err := NewWallet(walletPath) createWallet(t, walletPath, acc1, acc2, acc3)
require.NoError(t, err)
w.AddAccount(acc1)
w.AddAccount(acc2)
w.AddAccount(acc3)
require.NoError(t, w.savePretty())
w.Close()
} }
func regenerateWallets(t *testing.T, dir string) { func regenerateWallets(t *testing.T, dir string) {
@ -72,12 +66,7 @@ func regenerateWallets(t *testing.T, dir string) {
acc2 := getAccount(t, privnetWIFs[i], passwords[i]) acc2 := getAccount(t, privnetWIFs[i], passwords[i])
require.NoError(t, acc2.ConvertMultisig(3, pubs)) require.NoError(t, acc2.ConvertMultisig(3, pubs))
w, err := NewWallet(path.Join(dir, fmt.Sprintf("wallet%d.json", i+1))) createWallet(t, path.Join(dir, fmt.Sprintf("wallet%d.json", i+1)), acc1, acc2)
require.NoError(t, err)
w.AddAccount(acc1)
w.AddAccount(acc2)
require.NoError(t, w.savePretty())
w.Close()
} }
} }
@ -108,18 +97,96 @@ func TestRegenerateWalletTestdata(t *testing.T) {
acc3 := getAccount(t, privnetWIFs[1], "two") acc3 := getAccount(t, privnetWIFs[1], "two")
acc3.Default = true acc3.Default = true
w, err := NewWallet(path.Join(walletDir, "wallet1.json")) createWallet(t, path.Join(walletDir, "wallet1.json"), acc1, acc2)
require.NoError(t, err)
w.AddAccount(acc1)
w.AddAccount(acc2)
require.NoError(t, w.savePretty())
w.Close()
w, err = NewWallet(path.Join(walletDir, "wallet2.json")) createWallet(t, path.Join(walletDir, "wallet2.json"), acc1, acc2, acc3)
}
func TestRegenerateNotaryWallets(t *testing.T) {
if !regenerate {
return
}
const (
walletDir = "../services/notary/testdata/"
acc1WIF = "L1MstxuD8SvS9HuFcV5oYzcdA1xX8D9bD9qPwg8fU5SSywYBecg3"
acc2WIF = "L2iGxPvxbyWpYEbCZk2L3PgT7sCQaSDAbBC4MRLAjhs1s2JZ1xs5"
acc3WIF = "L1xD2yiUyARX8DAkWa8qGpWpwjqW2u717VzUJyByk6s7HinhRVZv"
acc4WIF = "L1ioz93TNt6Nu1aoMpZQ4zgdtgC8ZvJMC6pyHFkrovdR3SFwbn6n"
)
acc1 := getAccount(t, acc1WIF, "one")
acc2 := getAccount(t, acc2WIF, "one")
acc3 := getAccount(t, acc3WIF, "four")
createWallet(t, path.Join(walletDir, "notary1.json"), acc1, acc2, acc3)
acc4 := getAccount(t, acc4WIF, "two")
createWallet(t, path.Join(walletDir, "notary2.json"), acc4)
}
func TestRegenerateOracleWallets(t *testing.T) {
if !regenerate {
return
}
const (
walletDir = "../services/oracle/testdata/"
acc1WIF = "L38E2tRktb2kWc5j3Kx6Cg3ifVoi4DHhpVZrQormEFTT92C4iSUa"
acc2WIF = "KyA8z2MyLCSjJFG3F4SUp85CZ4WJm4qgWihFJZFEDYGEyw8oGcEP"
)
acc1 := getAccount(t, acc1WIF, "one")
createWallet(t, path.Join(walletDir, "oracle1.json"), acc1)
acc2 := getAccount(t, acc2WIF, "two")
createWallet(t, path.Join(walletDir, "oracle2.json"), acc2)
}
func TestRegenerateExamplesWallet(t *testing.T) {
if !regenerate {
return
}
const (
walletPath = "../../examples/my_wallet.json"
acc1WIF = "L46dn46AMZY7NQGZHemAdgcMabKon85eme45hgQkAUQBiRacY8MB"
)
acc1 := getAccount(t, acc1WIF, "qwerty")
acc1.Label = "my_account"
createWallet(t, walletPath, acc1)
}
func TestRegenerateCLITestwallet(t *testing.T) {
if !regenerate {
return
}
const (
walletPath = "../../cli/testdata/testwallet.json"
accWIF = "L23LrQNWELytYLvb5c6dXBDdF2DNPL9RRNWPqppv3roxacSnn8CN"
)
acc := getAccount(t, accWIF, "testpass")
acc.Label = "kek"
createWallet(t, walletPath, acc)
}
func TestRegenerateCLITestwallet_NEO3(t *testing.T) {
if !regenerate {
return
}
const walletPath = "../../cli/testdata/wallets/testwallet_NEO3.json"
pubs := getKeys(t)
acc1 := getAccount(t, privnetWIFs[0], passwords[0])
acc2 := getAccount(t, privnetWIFs[0], passwords[0])
require.NoError(t, acc2.ConvertMultisig(3, pubs))
createWallet(t, walletPath, acc1, acc2)
}
func createWallet(t *testing.T, path string, accs ...*Account) {
w, err := NewWallet(path)
require.NoError(t, err) require.NoError(t, err)
w.AddAccount(acc1) for _, acc := range accs {
w.AddAccount(acc2) w.AddAccount(acc)
w.AddAccount(acc3) }
require.NoError(t, w.savePretty()) require.NoError(t, w.savePretty())
w.Close() w.Close()
} }

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBdHR2qg==", "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0", "version": "3.0",
"accounts": [ "accounts": [
{ {
"address": "NTh9TnZTstvAePEYWDGLLxidBikJE24uTo", "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBdHR2qg==", "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -19,11 +19,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", "address": "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq",
"key": "6PYL8Gnjsz4RBKX18jx5ZAQTDH7PKkZwEVjPKEkjNzCDNFE6TKZwaFLibL", "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY",
"label": "", "label": "",
"contract": { "contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEGe0Nw6",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",
@ -44,11 +44,11 @@
"isdefault": false "isdefault": false
}, },
{ {
"address": "NUREbqw2kfbPgDeEz8Dac2QxntGGqqFMm7", "address": "NMUedC8TSV2rE17wGguSvPk9XcmHSaT275",
"key": "6PYXADog3RQCwKRhqQsobwZEFopdcCJuMfPosM9pXPaDWSguKvznLdpADk", "key": "6PYSYoZaxqDu5vqvm7yUFT3sPJJFwyLyYDnp8zwj1YVPcBWxacz64bNX59",
"label": "", "label": "",
"contract": { "contract": {
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG5BdHR2qg==", "script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG5BVuezJw==",
"parameters": [ "parameters": [
{ {
"name": "parameter0", "name": "parameter0",

View file

@ -188,16 +188,12 @@ func TestWalletGetChangeAddress(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
sh := w1.GetChangeAddress() sh := w1.GetChangeAddress()
// No default address, the first one is used. // No default address, the first one is used.
expected, err := address.StringToUint160("NTh9TnZTstvAePEYWDGLLxidBikJE24uTo") require.Equal(t, "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", address.Uint160ToString(sh))
require.NoError(t, err)
require.Equal(t, expected, sh)
w2, err := NewWalletFromFile("testdata/wallet2.json") w2, err := NewWalletFromFile("testdata/wallet2.json")
require.NoError(t, err) require.NoError(t, err)
sh = w2.GetChangeAddress() sh = w2.GetChangeAddress()
// Default address. // Default address.
expected, err = address.StringToUint160("NUREbqw2kfbPgDeEz8Dac2QxntGGqqFMm7") require.Equal(t, "NMUedC8TSV2rE17wGguSvPk9XcmHSaT275", address.Uint160ToString(sh))
require.NoError(t, err)
require.Equal(t, expected, sh)
} }
func TestWalletForExamples(t *testing.T) { func TestWalletForExamples(t *testing.T) {
@ -214,5 +210,5 @@ func TestWalletForExamples(t *testing.T) {
require.NoError(t, w.Accounts[0].Decrypt(walletPass)) require.NoError(t, w.Accounts[0].Decrypt(walletPass))
// we need to keep the owner of the example contracts the same as the wallet account // we need to keep the owner of the example contracts the same as the wallet account
require.Equal(t, "NX1yL5wDx3inK2qUVLRVaqCLUxYnAbv85S", w.Accounts[0].Address, "need to change `owner` in the example contracts") require.Equal(t, "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB", w.Accounts[0].Address, "need to change `owner` in the example contracts")
} }

View file

@ -99,7 +99,7 @@ func main() {
emit.AppCall(w.BinWriter, contractHash, "put", callflag.All, key, value) emit.AppCall(w.BinWriter, contractHash, "put", callflag.All, key, value)
handleError("can't create transaction", w.Err) handleError("can't create transaction", w.Err)
tx := transaction.New(w.Bytes(), 4_000_000) tx := transaction.New(w.Bytes(), 4_040_000)
tx.ValidUntilBlock = i + 1 tx.ValidUntilBlock = i + 1
tx.NetworkFee = 4_000_000 tx.NetworkFee = 4_000_000
tx.Nonce = nonce tx.Nonce = nonce