Merge pull request #1175 from nspcc-dev/neo3/crypto/ecdsa
crypto: add Secp256k1 support
This commit is contained in:
commit
75dc62fa81
40 changed files with 366 additions and 215 deletions
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -44,11 +44,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "NYqxsNMHxDg3T19APYP27mBZFfauC4zngR",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NVNvVRW5Q5naSx2k2iZm7xRgtRNGuZppAK",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEQtBMHOzuw==",
|
||||
"script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEQtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ",
|
||||
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
|
||||
"address": "NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5",
|
||||
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQQqQatQ=",
|
||||
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "Nfzhk6dtjLZE93iGkqYv5pwrTW5QRQk5bV",
|
||||
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
|
||||
"address": "NNB3RsnTABEwoKEudNG92njds91WtiCuxd",
|
||||
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQQqQatQ=",
|
||||
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NU5BGveyZSQ7TUAxRnKVDXgE9oExpzV5vY",
|
||||
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
|
||||
"address": "Nfzo95iBXfeAGx5rdjPedZRAqHKh9hwMdR",
|
||||
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQQqQatQ=",
|
||||
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/nspcc-dev/neo-go
|
|||
require (
|
||||
github.com/Workiva/go-datastructures v1.0.50
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible
|
||||
github.com/btcsuite/btcd v0.20.1-beta
|
||||
github.com/dgraph-io/badger/v2 v2.0.3
|
||||
github.com/frankban/quicktest v1.10.0 // indirect
|
||||
github.com/go-redis/redis v6.10.2+incompatible
|
||||
|
|
28
go.sum
28
go.sum
|
@ -13,6 +13,8 @@ github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma
|
|||
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
|
||||
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8=
|
||||
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530=
|
||||
github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
|
@ -28,6 +30,22 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
|||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd h1:qdGvebPBDuYDPGi1WCPjy1tGyMpmDK8IEapSsszn7HE=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723 h1:ZA/jbKoGcVAnER6pCHPEkGdZOV7U1oLUedErBHCUMs0=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
|
||||
|
@ -41,6 +59,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
|
|||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
@ -95,9 +114,15 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
|
|||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
|
@ -150,10 +175,12 @@ github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYv
|
|||
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
|
||||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
|
@ -220,6 +247,7 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
|||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
|
|
|
@ -6,7 +6,10 @@ var syscalls = map[string]map[string]string{
|
|||
"Deserialize": "System.Binary.Deserialize",
|
||||
},
|
||||
"crypto": {
|
||||
"ECDsaVerify": "Neo.Crypto.ECDsaVerify",
|
||||
"ECDsaSecp256r1Verify": "Neo.Crypto.VerifyWithECDsaSecp256r1",
|
||||
"ECDsaSecp256k1Verify": "Neo.Crypto.VerifyWithECDsaSecp256k1",
|
||||
"ECDSASecp256r1CheckMultisig": "Neo.Crypto.CheckMultisigWithECDsaSecp256r1",
|
||||
"ECDSASecp256k1CheckMultisig": "Neo.Crypto.CheckMultisigWithECDsaSecp256k1",
|
||||
},
|
||||
"enumerator": {
|
||||
"Concat": "System.Enumerator.Concat",
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestVerifyGood(t *testing.T) {
|
|||
src := getVerifyProg(pub, sig, msg)
|
||||
|
||||
v, p := vmAndCompileInterop(t, src)
|
||||
p.interops[emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))] = func(v *vm.VM) error {
|
||||
p.interops[emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))] = func(v *vm.VM) error {
|
||||
assert.Equal(t, msg, v.Estack().Pop().Bytes())
|
||||
assert.Equal(t, pub, v.Estack().Pop().Bytes())
|
||||
assert.Equal(t, sig, v.Estack().Pop().Bytes())
|
||||
|
@ -54,7 +54,7 @@ func getVerifyProg(pub, sig, msg []byte) string {
|
|||
pub := ` + pubS + `
|
||||
sig := ` + sigS + `
|
||||
msg := ` + msgS + `
|
||||
return crypto.ECDsaVerify(msg, pub, sig)
|
||||
return crypto.ECDsaSecp256r1Verify(msg, pub, sig)
|
||||
}
|
||||
`
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package consensus
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
|
@ -75,6 +74,7 @@ func TestConsensusPayload_Setters(t *testing.T) {
|
|||
require.Equal(t, pl, p.GetRecoveryMessage())
|
||||
}
|
||||
|
||||
/*// TODO: update binary (see https://github.com/nspcc-dev/neo-go/issues/1178)
|
||||
func TestConsensusPayload_Verify(t *testing.T) {
|
||||
// signed payload from testnet
|
||||
dataHex := "00000000a70b769e4af60878f6daa72be41770c62592c694bf9ead6b16b30ad90f28c4098cc704000400423000d5b4baae11191ac370a4d7860df01824fcea7f934d6461db6d4b7966ca3c135c8c262b7f23bbac13e73885223604141e062234d999068d9a74b77caeeb5271cf01420c4055ae8c7694c296e92da393f944b0dc1cd70d12de3ee944e9afc872d1db427fe87fcbe913709a8ec73e2f5acdfc0b7f0a96e9d63bad0a20e3226c882237f5c771290c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0b410a906ad4"
|
||||
|
@ -89,7 +89,7 @@ func TestConsensusPayload_Verify(t *testing.T) {
|
|||
require.NoError(t, p.decodeData())
|
||||
require.True(t, p.Verify(h))
|
||||
}
|
||||
|
||||
*/
|
||||
func TestConsensusPayload_Serializable(t *testing.T) {
|
||||
for _, mt := range messageTypes {
|
||||
p := randomPayload(t, mt)
|
||||
|
|
12
pkg/consensus/testdata/wallet1.json
vendored
12
pkg/consensus/testdata/wallet1.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
12
pkg/consensus/testdata/wallet2.json
vendored
12
pkg/consensus/testdata/wallet2.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ",
|
||||
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
|
||||
"address": "NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5",
|
||||
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQQqQatQ=",
|
||||
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
12
pkg/consensus/testdata/wallet3.json
vendored
12
pkg/consensus/testdata/wallet3.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "Nfzhk6dtjLZE93iGkqYv5pwrTW5QRQk5bV",
|
||||
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
|
||||
"address": "NNB3RsnTABEwoKEudNG92njds91WtiCuxd",
|
||||
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQQqQatQ=",
|
||||
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
12
pkg/consensus/testdata/wallet4.json
vendored
12
pkg/consensus/testdata/wallet4.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NU5BGveyZSQ7TUAxRnKVDXgE9oExpzV5vY",
|
||||
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
|
||||
"address": "Nfzo95iBXfeAGx5rdjPedZRAqHKh9hwMdR",
|
||||
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQQqQatQ=",
|
||||
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
|
@ -15,13 +17,24 @@ import (
|
|||
// ECDSAVerifyPrice is a gas price of a single verification.
|
||||
const ECDSAVerifyPrice = 1000000
|
||||
|
||||
// ECDSAVerify checks ECDSA signature.
|
||||
func ECDSAVerify(ic *interop.Context, v *vm.VM) error {
|
||||
// ECDSASecp256r1Verify checks ECDSA signature using Secp256r1 elliptic curve.
|
||||
func ECDSASecp256r1Verify(ic *interop.Context, v *vm.VM) error {
|
||||
return ecdsaVerify(ic, v, elliptic.P256())
|
||||
}
|
||||
|
||||
// ECDSASecp256k1Verify checks ECDSA signature using Secp256k1 elliptic curve
|
||||
func ECDSASecp256k1Verify(ic *interop.Context, v *vm.VM) error {
|
||||
return ecdsaVerify(ic, v, btcec.S256())
|
||||
}
|
||||
|
||||
// ecdsaVerify is internal representation of ECDSASecp256k1Verify and
|
||||
// ECDSASecp256r1Verify.
|
||||
func ecdsaVerify(ic *interop.Context, v *vm.VM, curve elliptic.Curve) error {
|
||||
msg := getMessage(ic, v.Estack().Pop().Item())
|
||||
hashToCheck := hash.Sha256(msg).BytesBE()
|
||||
keyb := v.Estack().Pop().Bytes()
|
||||
signature := v.Estack().Pop().Bytes()
|
||||
pkey, err := keys.NewPublicKeyFromBytes(keyb)
|
||||
pkey, err := keys.NewPublicKeyFromBytes(keyb, curve)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -30,8 +43,21 @@ func ECDSAVerify(ic *interop.Context, v *vm.VM) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ECDSACheckMultisig checks multiple ECDSA signatures at once.
|
||||
func ECDSACheckMultisig(ic *interop.Context, v *vm.VM) error {
|
||||
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once using
|
||||
// Secp256r1 elliptic curve.
|
||||
func ECDSASecp256r1CheckMultisig(ic *interop.Context, v *vm.VM) error {
|
||||
return ecdsaCheckMultisig(ic, v, elliptic.P256())
|
||||
}
|
||||
|
||||
// ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once using
|
||||
// Secp256k1 elliptic curve.
|
||||
func ECDSASecp256k1CheckMultisig(ic *interop.Context, v *vm.VM) error {
|
||||
return ecdsaCheckMultisig(ic, v, btcec.S256())
|
||||
}
|
||||
|
||||
// ecdsaCheckMultisig is internal representation of ECDSASecp256r1CheckMultisig and
|
||||
// ECDSASecp256k1CheckMultisig
|
||||
func ecdsaCheckMultisig(ic *interop.Context, v *vm.VM, curve elliptic.Curve) error {
|
||||
msg := getMessage(ic, v.Estack().Pop().Item())
|
||||
hashToCheck := hash.Sha256(msg).BytesBE()
|
||||
pkeys, err := v.Estack().PopSigElements()
|
||||
|
@ -50,7 +76,7 @@ func ECDSACheckMultisig(ic *interop.Context, v *vm.VM) error {
|
|||
if len(pkeys) < len(sigs) {
|
||||
return errors.New("more signatures than there are keys")
|
||||
}
|
||||
sigok := vm.CheckMultisigPar(v, hashToCheck, pkeys, sigs)
|
||||
sigok := vm.CheckMultisigPar(v, curve, hashToCheck, pkeys, sigs)
|
||||
v.Estack().PushVal(sigok)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ func subSlice(arr []stackitem.Item, indices []int) []stackitem.Item {
|
|||
func initCHECKMULTISIGVM(t *testing.T, n int, ik, is []int) *vm.VM {
|
||||
buf := make([]byte, 5)
|
||||
buf[0] = byte(opcode.SYSCALL)
|
||||
binary.LittleEndian.PutUint32(buf[1:], ecdsaCheckMultisigID)
|
||||
binary.LittleEndian.PutUint32(buf[1:], ecdsaSecp256r1CheckMultisigID)
|
||||
|
||||
v := vm.New()
|
||||
v.GasLimit = -1
|
||||
|
|
|
@ -7,25 +7,25 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ecdsaVerifyID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
|
||||
ecdsaCheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
|
||||
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256"))
|
||||
ecdsaSecp256r1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))
|
||||
ecdsaSecp256r1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1"))
|
||||
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256"))
|
||||
)
|
||||
|
||||
// GetInterop returns interop getter for crypto-related stuff.
|
||||
func GetInterop(ic *interop.Context) func(uint32) *vm.InteropFuncPrice {
|
||||
return func(id uint32) *vm.InteropFuncPrice {
|
||||
switch id {
|
||||
case ecdsaVerifyID:
|
||||
case ecdsaSecp256r1VerifyID:
|
||||
return &vm.InteropFuncPrice{
|
||||
Func: func(v *vm.VM) error {
|
||||
return ECDSAVerify(ic, v)
|
||||
return ECDSASecp256r1Verify(ic, v)
|
||||
},
|
||||
}
|
||||
case ecdsaCheckMultisigID:
|
||||
case ecdsaSecp256r1CheckMultisigID:
|
||||
return &vm.InteropFuncPrice{
|
||||
Func: func(v *vm.VM) error {
|
||||
return ECDSACheckMultisig(ic, v)
|
||||
return ECDSASecp256r1CheckMultisig(ic, v)
|
||||
},
|
||||
}
|
||||
case sha256ID:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
|
||||
"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/transaction"
|
||||
|
@ -90,7 +92,7 @@ func CheckWitness(ic *interop.Context, v *vm.VM) error {
|
|||
hash, err := util.Uint160DecodeBytesBE(hashOrKey)
|
||||
if err != nil {
|
||||
var key *keys.PublicKey
|
||||
key, err = keys.NewPublicKeyFromBytes(hashOrKey)
|
||||
key, err = keys.NewPublicKeyFromBytes(hashOrKey, elliptic.P256())
|
||||
if err != nil {
|
||||
return errors.New("parameter given is neither a key nor a hash")
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ func TestECDSAVerify(t *testing.T) {
|
|||
err = fmt.Errorf("panic: %v", r)
|
||||
}
|
||||
}()
|
||||
err = crypto.ECDSAVerify(ic, v)
|
||||
err = crypto.ECDSASecp256r1Verify(ic, v)
|
||||
}()
|
||||
|
||||
if isErr {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
@ -492,7 +493,7 @@ func contractIsStandard(ic *interop.Context, v *vm.VM) error {
|
|||
// contractCreateStandardAccount calculates contract scripthash for a given public key.
|
||||
func contractCreateStandardAccount(ic *interop.Context, v *vm.VM) error {
|
||||
h := v.Estack().Pop().Bytes()
|
||||
p, err := keys.NewPublicKeyFromBytes(h)
|
||||
p, err := keys.NewPublicKeyFromBytes(h, elliptic.P256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -138,8 +138,10 @@ var systemInterops = []interop.Function{
|
|||
}
|
||||
|
||||
var neoInterops = []interop.Function{
|
||||
{Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: crypto.ECDSAVerifyPrice},
|
||||
{Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 0},
|
||||
{Name: "Neo.Crypto.VerifyWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1Verify, Price: crypto.ECDSAVerifyPrice},
|
||||
{Name: "Neo.Crypto.VerifyWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1Verify, Price: crypto.ECDSAVerifyPrice},
|
||||
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0},
|
||||
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1CheckMultisig, Price: 0},
|
||||
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1000000},
|
||||
{Name: "Neo.Native.Deploy", Func: native.Deploy, Price: 0,
|
||||
AllowedTriggers: trigger.Application, RequiredFlags: smartcontract.AllowModifyStates},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package native
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strings"
|
||||
|
@ -361,7 +362,7 @@ func (n *NEO) GetRegisteredValidators(d dao.DAO) ([]state.Validator, error) {
|
|||
}
|
||||
arr := make([]state.Validator, len(kvs))
|
||||
for i := range kvs {
|
||||
arr[i].Key, err = keys.NewPublicKeyFromBytes([]byte(kvs[i].Key))
|
||||
arr[i].Key, err = keys.NewPublicKeyFromBytes([]byte(kvs[i].Key), elliptic.P256())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -21,14 +21,14 @@ func TestGenesisBlockMainNet(t *testing.T) {
|
|||
// have been changed. Consequently, hash of the genesis block has been changed.
|
||||
// Update expected genesis block hash for better times.
|
||||
// Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf"
|
||||
expect := "dba446947a90b2862ef050703b44828ad8b02d11978f8ef59bd3e1c97aabf6e5"
|
||||
expect := "94e61af2441145cc251752707a58107850328a48bb095fd175ca2f8513ab5676"
|
||||
assert.Equal(t, expect, block.Hash().StringLE())
|
||||
}
|
||||
|
||||
func TestGetConsensusAddressMainNet(t *testing.T) {
|
||||
var (
|
||||
consensusAddr = "NWNnqYniJyFh1qx5KyBeTV4uq5ewvNrAuD"
|
||||
consensusScript = "72c3d9b3bbf776698694cd2c73fa597a10c31294"
|
||||
consensusAddr = "NiVihDFvZacZhujTWkBhRz32UDuNRp416f"
|
||||
consensusScript = "f7b4d00143932f3b6243cfc06cb4a68f22c739e2"
|
||||
)
|
||||
|
||||
cfg, err := config.Load("../../config", netmode.MainNet)
|
||||
|
|
|
@ -14,21 +14,31 @@ import (
|
|||
"github.com/nspcc-dev/rfc6979"
|
||||
)
|
||||
|
||||
// PrivateKey represents a NEO private key.
|
||||
// PrivateKey represents a NEO private key and provides a high level API around
|
||||
// ecdsa.PrivateKey.
|
||||
type PrivateKey struct {
|
||||
b []byte
|
||||
ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// NewPrivateKey creates a new random private key.
|
||||
// NewPrivateKey creates a new random Secp256k1 private key.
|
||||
func NewPrivateKey() (*PrivateKey, error) {
|
||||
priv, _, _, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
priv, x, y, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PrivateKey{b: priv}, nil
|
||||
return &PrivateKey{
|
||||
ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: x,
|
||||
Y: y,
|
||||
},
|
||||
D: new(big.Int).SetBytes(priv),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewPrivateKeyFromHex returns a PrivateKey created from the
|
||||
// NewPrivateKeyFromHex returns a Secp256k1 PrivateKey created from the
|
||||
// given hex string.
|
||||
func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
|
||||
b, err := hex.DecodeString(str)
|
||||
|
@ -38,17 +48,35 @@ func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
|
|||
return NewPrivateKeyFromBytes(b)
|
||||
}
|
||||
|
||||
// NewPrivateKeyFromBytes returns a NEO PrivateKey from the given byte slice.
|
||||
// NewPrivateKeyFromBytes returns a NEO Secp256r1 PrivateKey from the given
|
||||
// byte slice.
|
||||
func NewPrivateKeyFromBytes(b []byte) (*PrivateKey, error) {
|
||||
if len(b) != 32 {
|
||||
return nil, fmt.Errorf(
|
||||
"invalid byte length: expected %d bytes got %d", 32, len(b),
|
||||
)
|
||||
}
|
||||
return &PrivateKey{b}, nil
|
||||
var (
|
||||
c = elliptic.P256()
|
||||
d = new(big.Int).SetBytes(b)
|
||||
)
|
||||
|
||||
x, y := c.ScalarBaseMult(d.Bytes())
|
||||
|
||||
return &PrivateKey{
|
||||
ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: c,
|
||||
X: x,
|
||||
Y: y,
|
||||
},
|
||||
D: d,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewPrivateKeyFromASN1 returns a NEO PrivateKey from the ASN.1 serialized key.
|
||||
// NewPrivateKeyFromASN1 returns a NEO Secp256k1 PrivateKey from the ASN.1
|
||||
// serialized key.
|
||||
func NewPrivateKeyFromASN1(b []byte) (*PrivateKey, error) {
|
||||
privkey, err := x509.ParseECPrivateKey(b)
|
||||
if err != nil {
|
||||
|
@ -59,14 +87,8 @@ func NewPrivateKeyFromASN1(b []byte) (*PrivateKey, error) {
|
|||
|
||||
// PublicKey derives the public key from the private key.
|
||||
func (p *PrivateKey) PublicKey() *PublicKey {
|
||||
var (
|
||||
c = elliptic.P256()
|
||||
q = new(big.Int).SetBytes(p.b)
|
||||
)
|
||||
|
||||
x, y := c.ScalarBaseMult(q.Bytes())
|
||||
|
||||
return &PublicKey{X: x, Y: y}
|
||||
result := PublicKey(p.PrivateKey.PublicKey)
|
||||
return &result
|
||||
}
|
||||
|
||||
// NewPrivateKeyFromWIF returns a NEO PrivateKey from the given
|
||||
|
@ -83,7 +105,7 @@ func NewPrivateKeyFromWIF(wif string) (*PrivateKey, error) {
|
|||
// Good documentation about this process can be found here:
|
||||
// https://en.bitcoin.it/wiki/Wallet_import_format
|
||||
func (p *PrivateKey) WIF() string {
|
||||
w, err := WIFEncode(p.b, WIFVersion, true)
|
||||
w, err := WIFEncode(p.Bytes(), WIFVersion, true)
|
||||
// The only way WIFEncode() can fail is if we're to give it a key of
|
||||
// wrong size, but we have a proper key here, aren't we?
|
||||
if err != nil {
|
||||
|
@ -109,7 +131,7 @@ func (p *PrivateKey) GetScriptHash() util.Uint160 {
|
|||
// Sign signs arbitrary length data using the private key.
|
||||
func (p *PrivateKey) Sign(data []byte) []byte {
|
||||
var (
|
||||
privateKey = p.ecdsa()
|
||||
privateKey = &p.PrivateKey
|
||||
digest = sha256.Sum256(data)
|
||||
)
|
||||
|
||||
|
@ -125,21 +147,16 @@ func (p *PrivateKey) Sign(data []byte) []byte {
|
|||
return signature
|
||||
}
|
||||
|
||||
// ecsda converts the key to a usable ecsda.PrivateKey for signing data.
|
||||
func (p *PrivateKey) ecdsa() *ecdsa.PrivateKey {
|
||||
priv := new(ecdsa.PrivateKey)
|
||||
priv.PublicKey.Curve = elliptic.P256()
|
||||
priv.D = new(big.Int).SetBytes(p.b)
|
||||
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(p.b)
|
||||
return priv
|
||||
}
|
||||
|
||||
// String implements the stringer interface.
|
||||
func (p *PrivateKey) String() string {
|
||||
return hex.EncodeToString(p.b)
|
||||
return hex.EncodeToString(p.Bytes())
|
||||
}
|
||||
|
||||
// Bytes returns the underlying bytes of the PrivateKey.
|
||||
func (p *PrivateKey) Bytes() []byte {
|
||||
return p.b
|
||||
bytes := p.D.Bytes()
|
||||
result := make([]byte, 32)
|
||||
copy(result[32-len(bytes):], bytes)
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -76,11 +77,8 @@ func (keys PublicKeys) Unique() PublicKeys {
|
|||
}
|
||||
|
||||
// PublicKey represents a public key and provides a high level
|
||||
// API around the X/Y point.
|
||||
type PublicKey struct {
|
||||
X *big.Int
|
||||
Y *big.Int
|
||||
}
|
||||
// API around ecdsa.PublicKey.
|
||||
type PublicKey ecdsa.PublicKey
|
||||
|
||||
// Equal returns true in case public keys are equal.
|
||||
func (p *PublicKey) Equal(key *PublicKey) bool {
|
||||
|
@ -103,12 +101,13 @@ func NewPublicKeyFromString(s string) (*PublicKey, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewPublicKeyFromBytes(b)
|
||||
return NewPublicKeyFromBytes(b, elliptic.P256())
|
||||
}
|
||||
|
||||
// NewPublicKeyFromBytes returns public key created from b.
|
||||
func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) {
|
||||
// NewPublicKeyFromBytes returns public key created from b using given EC.
|
||||
func NewPublicKeyFromBytes(b []byte, curve elliptic.Curve) (*PublicKey, error) {
|
||||
pubKey := new(PublicKey)
|
||||
pubKey.Curve = curve
|
||||
if err := pubKey.DecodeBytes(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -173,23 +172,30 @@ func NewPublicKeyFromASN1(data []byte) (*PublicKey, error) {
|
|||
if !ok {
|
||||
return nil, errors.New("given bytes aren't ECDSA public key")
|
||||
}
|
||||
key := PublicKey{
|
||||
X: pk.X,
|
||||
Y: pk.Y,
|
||||
}
|
||||
return &key, nil
|
||||
result := PublicKey(*pk)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// decodeCompressedY performs decompression of Y coordinate for given X and Y's least significant bit.
|
||||
func decodeCompressedY(x *big.Int, ylsb uint) (*big.Int, error) {
|
||||
c := elliptic.P256()
|
||||
cp := c.Params()
|
||||
three := big.NewInt(3)
|
||||
/* y**2 = x**3 + a*x + b % p */
|
||||
xCubed := new(big.Int).Exp(x, three, cp.P)
|
||||
threeX := new(big.Int).Mul(x, three)
|
||||
threeX.Mod(threeX, cp.P)
|
||||
ySquared := new(big.Int).Sub(xCubed, threeX)
|
||||
// We use here a short-form Weierstrass curve (https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html)
|
||||
// y² = x³ + ax + b. Two types of elliptic curves are supported:
|
||||
// 1. Secp256k1 (Koblitz curve): y² = x³ + b,
|
||||
// 2. Secp256r1 (Random curve): y² = x³ - 3x + b.
|
||||
// To decode compressed curve point we perform the following operation: y = sqrt(x³ + ax + b mod p)
|
||||
// where `p` denotes the order of the underlying curve field
|
||||
func decodeCompressedY(x *big.Int, ylsb uint, curve elliptic.Curve) (*big.Int, error) {
|
||||
var a *big.Int
|
||||
switch curve.(type) {
|
||||
case *btcec.KoblitzCurve:
|
||||
a = big.NewInt(0)
|
||||
default:
|
||||
a = big.NewInt(3)
|
||||
}
|
||||
cp := curve.Params()
|
||||
xCubed := new(big.Int).Exp(x, big.NewInt(3), cp.P)
|
||||
aX := new(big.Int).Mul(x, a)
|
||||
aX.Mod(aX, cp.P)
|
||||
ySquared := new(big.Int).Sub(xCubed, aX)
|
||||
ySquared.Add(ySquared, cp.B)
|
||||
ySquared.Mod(ySquared, cp.P)
|
||||
y := new(big.Int).ModSqrt(ySquared, cp.P)
|
||||
|
@ -210,7 +216,8 @@ func (p *PublicKey) DecodeBytes(data []byte) error {
|
|||
return b.Err
|
||||
}
|
||||
|
||||
// DecodeBinary decodes a PublicKey from the given BinReader.
|
||||
// DecodeBinary decodes a PublicKey from the given BinReader using information
|
||||
// about the EC curve to decompress Y point. Secp256r1 is a default value for EC curve.
|
||||
func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
||||
var prefix uint8
|
||||
var x, y *big.Int
|
||||
|
@ -221,8 +228,11 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
|||
return
|
||||
}
|
||||
|
||||
p256 := elliptic.P256()
|
||||
p256Params := p256.Params()
|
||||
if p.Curve == nil {
|
||||
p.Curve = elliptic.P256()
|
||||
}
|
||||
curve := p.Curve
|
||||
curveParams := p.Params()
|
||||
// Infinity
|
||||
switch prefix {
|
||||
case 0x00:
|
||||
|
@ -237,7 +247,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
|||
}
|
||||
x = new(big.Int).SetBytes(xbytes)
|
||||
ylsb := uint(prefix & 0x1)
|
||||
y, err = decodeCompressedY(x, ylsb)
|
||||
y, err = decodeCompressedY(x, ylsb, curve)
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
|
@ -252,7 +262,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
|||
}
|
||||
x = new(big.Int).SetBytes(xbytes)
|
||||
y = new(big.Int).SetBytes(ybytes)
|
||||
if !p256.IsOnCurve(x, y) {
|
||||
if !curve.IsOnCurve(x, y) {
|
||||
r.Err = errors.New("encoded point is not on the P256 curve")
|
||||
return
|
||||
}
|
||||
|
@ -260,7 +270,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
|||
r.Err = errors.Errorf("invalid prefix %d", prefix)
|
||||
return
|
||||
}
|
||||
if x.Cmp(p256Params.P) >= 0 || y.Cmp(p256Params.P) >= 0 {
|
||||
if x.Cmp(curveParams.P) >= 0 || y.Cmp(curveParams.P) >= 0 {
|
||||
r.Err = errors.New("enccoded point is not correct (X or Y is bigger than P")
|
||||
return
|
||||
}
|
||||
|
@ -285,7 +295,7 @@ func (p *PublicKey) GetVerificationScript() []byte {
|
|||
}
|
||||
emit.Bytes(buf.BinWriter, b)
|
||||
emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
|
||||
emit.Syscall(buf.BinWriter, "Neo.Crypto.ECDsaVerify")
|
||||
emit.Syscall(buf.BinWriter, "Neo.Crypto.VerifyWithECDsaSecp256r1")
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
@ -303,17 +313,13 @@ func (p *PublicKey) Address() string {
|
|||
// Verify returns true if the signature is valid and corresponds
|
||||
// to the hash and public key.
|
||||
func (p *PublicKey) Verify(signature []byte, hash []byte) bool {
|
||||
|
||||
publicKey := &ecdsa.PublicKey{}
|
||||
publicKey.Curve = elliptic.P256()
|
||||
publicKey.X = p.X
|
||||
publicKey.Y = p.Y
|
||||
if p.X == nil || p.Y == nil {
|
||||
return false
|
||||
}
|
||||
rBytes := new(big.Int).SetBytes(signature[0:32])
|
||||
sBytes := new(big.Int).SetBytes(signature[32:64])
|
||||
return ecdsa.Verify(publicKey, hash, rBytes, sBytes)
|
||||
pk := ecdsa.PublicKey(*p)
|
||||
return ecdsa.Verify(&pk, hash, rBytes, sBytes)
|
||||
}
|
||||
|
||||
// IsInfinity checks if the key is infinite (null, basically).
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package keys
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
|
@ -59,7 +60,7 @@ func TestNewPublicKeyFromBytes(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
b := priv.PublicKey().Bytes()
|
||||
pub, err := NewPublicKeyFromBytes(b)
|
||||
pub, err := NewPublicKeyFromBytes(b, elliptic.P256())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, priv.PublicKey(), pub)
|
||||
}
|
||||
|
@ -106,7 +107,7 @@ func TestPubkeyToAddress(t *testing.T) {
|
|||
pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
|
||||
require.NoError(t, err)
|
||||
actual := pubKey.Address()
|
||||
expected := "NNqoUeNb2tfhEExY7mrPbxf4EZZRKX5nHF"
|
||||
expected := "NcKJdJTEDeCSV9BJAKWWxkBMcHTeVnSzJo"
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +1,81 @@
|
|||
package keys
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPubKeyVerify(t *testing.T) {
|
||||
var data = []byte("sample")
|
||||
hashedData := hash.Sha256(data)
|
||||
|
||||
privKey, err := NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
signedData := privKey.Sign(data)
|
||||
pubKey := privKey.PublicKey()
|
||||
result := pubKey.Verify(signedData, hashedData.BytesBE())
|
||||
expected := true
|
||||
assert.Equal(t, expected, result)
|
||||
t.Run("Secp256r1", func(t *testing.T) {
|
||||
privKey, err := NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
signedData := privKey.Sign(data)
|
||||
pubKey := privKey.PublicKey()
|
||||
result := pubKey.Verify(signedData, hashedData.BytesBE())
|
||||
expected := true
|
||||
assert.Equal(t, expected, result)
|
||||
|
||||
pubKey = &PublicKey{}
|
||||
assert.False(t, pubKey.Verify(signedData, hashedData.BytesBE()))
|
||||
pubKey = &PublicKey{}
|
||||
assert.False(t, pubKey.Verify(signedData, hashedData.BytesBE()))
|
||||
})
|
||||
|
||||
t.Run("Secp256k1", func(t *testing.T) {
|
||||
privateKey, err := btcec.NewPrivateKey(btcec.S256())
|
||||
assert.Nil(t, err)
|
||||
signature, err := privateKey.Sign(hashedData.BytesBE())
|
||||
require.NoError(t, err)
|
||||
signedData := append(signature.R.Bytes(), signature.S.Bytes()...)
|
||||
pubKey := PublicKey(ecdsa.PublicKey{
|
||||
Curve: btcec.S256(),
|
||||
X: privateKey.X,
|
||||
Y: privateKey.Y,
|
||||
})
|
||||
require.True(t, pubKey.Verify(signedData, hashedData.BytesBE()))
|
||||
|
||||
pubKey = PublicKey{}
|
||||
assert.False(t, pubKey.Verify(signedData, hashedData.BytesBE()))
|
||||
})
|
||||
}
|
||||
|
||||
func TestWrongPubKey(t *testing.T) {
|
||||
privKey, _ := NewPrivateKey()
|
||||
sample := []byte("sample")
|
||||
hashedData := hash.Sha256(sample)
|
||||
signedData := privKey.Sign(sample)
|
||||
|
||||
secondPrivKey, _ := NewPrivateKey()
|
||||
wrongPubKey := secondPrivKey.PublicKey()
|
||||
t.Run("Secp256r1", func(t *testing.T) {
|
||||
privKey, _ := NewPrivateKey()
|
||||
signedData := privKey.Sign(sample)
|
||||
|
||||
actual := wrongPubKey.Verify(signedData, hashedData.BytesBE())
|
||||
expcted := false
|
||||
assert.Equal(t, expcted, actual)
|
||||
secondPrivKey, _ := NewPrivateKey()
|
||||
wrongPubKey := secondPrivKey.PublicKey()
|
||||
|
||||
actual := wrongPubKey.Verify(signedData, hashedData.BytesBE())
|
||||
expcted := false
|
||||
assert.Equal(t, expcted, actual)
|
||||
})
|
||||
|
||||
t.Run("Secp256k1", func(t *testing.T) {
|
||||
privateKey, err := btcec.NewPrivateKey(btcec.S256())
|
||||
assert.Nil(t, err)
|
||||
signature, err := privateKey.Sign(hashedData.BytesBE())
|
||||
assert.Nil(t, err)
|
||||
signedData := append(signature.R.Bytes(), signature.S.Bytes()...)
|
||||
|
||||
secondPrivKey, err := btcec.NewPrivateKey(btcec.S256())
|
||||
assert.Nil(t, err)
|
||||
wrongPubKey := PublicKey(ecdsa.PublicKey{
|
||||
Curve: btcec.S256(),
|
||||
X: secondPrivKey.X,
|
||||
Y: secondPrivKey.Y,
|
||||
})
|
||||
|
||||
assert.False(t, wrongPubKey.Verify(signedData, hashedData.BytesBE()))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,28 +14,28 @@ type Ktype struct {
|
|||
// Arr contains a set of known keys in Ktype format.
|
||||
var Arr = []Ktype{
|
||||
{
|
||||
Address: "NMPAXGtMfZ8s8rcfP9JhrYrNeZHG4xSVmd",
|
||||
Address: "NNWAo5vdVJz1oyCuNiaTBA3amBHnWCF4Yk",
|
||||
PrivateKey: "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344",
|
||||
PublicKey: "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef",
|
||||
Wif: "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g",
|
||||
Passphrase: "city of zion",
|
||||
EncryptedWif: "6PYWdzMKGbfxHbfb2JqZJ5Yr1y6jjjuSPLjvgS4byvDkgz2NdiBgeJwBFc",
|
||||
EncryptedWif: "6PYSeMMbJtfMRD81eHzriwrRKquu2dgLNurYcAbmJa7YqAiThgA2vGQu5o",
|
||||
},
|
||||
{
|
||||
Address: "NRC6oteucWYXq7aASD6YWe5rNeXAw1ehye",
|
||||
Address: "NiwvMyWYeNghLG8tDyKkWwuZV3wS8CPrrV",
|
||||
PrivateKey: "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69",
|
||||
PublicKey: "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9",
|
||||
Wif: "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG",
|
||||
Passphrase: "我的密码",
|
||||
EncryptedWif: "6PYLxXgqE8MaQJr3NR96rfFBxzdNLytb3CfxeDXyijSEG2M1vF9d4CoRAg",
|
||||
EncryptedWif: "6PYKWKaq5NMyjt8cjvnJnvmV13inhFuePpWZMkddFAMCgjC3ETt7kX16V9",
|
||||
},
|
||||
{
|
||||
Address: "NTFAwXLGoiWwSMP5vJyZp8K4cBFwrzUs8m",
|
||||
Address: "NTWHAzB82LRGWNuuqjVyyzpGvF3WxbbPoG",
|
||||
PrivateKey: "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b",
|
||||
PublicKey: "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
|
||||
Wif: "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
|
||||
Passphrase: "MyL33tP@33w0rd",
|
||||
EncryptedWif: "6PYRoabFnWARA3ZWwfJ4efQ4uuuB9WdVrA1LFbMkZLtXZ2DJg3bzjiK59s",
|
||||
EncryptedWif: "6PYSzKoJBQMj9uHUv1Sc2ZhMrydqDF8ZCTeE9FuPiNdEx7Lo9NoEuaXeyk",
|
||||
},
|
||||
{
|
||||
Address: "xdf4UGKevVrMR1j3UkPsuoYKSC4ocoAkKx",
|
||||
|
@ -43,7 +43,7 @@ var Arr = []Ktype{
|
|||
PublicKey: "zz232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
|
||||
Wif: "zzKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
|
||||
Passphrase: "zzL33tP@33w0rd",
|
||||
EncryptedWif: "6PYRoabFnWARA3ZWwfJ4efQ4uuuB9WdVrA1LFbMkZLtXZ2DJg3bzjiK59s",
|
||||
EncryptedWif: "6PYSzKoJBQMj9uHUv1Sc2ZhMrydqDF8ZCTeE9FuPiNdEx7Lo9NoEuaXeyk",
|
||||
Invalid: true,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -8,8 +8,26 @@ func SHA256(b []byte) []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ECDsaVerify checks that sig is correct msg's signature for a given pub
|
||||
// (serialized public key). It uses `Neo.Crypto.ECDsaVerify` syscall.
|
||||
func ECDsaVerify(msg []byte, pub []byte, sig []byte) bool {
|
||||
// ECDsaSecp256r1Verify checks that sig is correct msg's signature for a given pub
|
||||
// (serialized public key). It uses `Neo.Crypto.VerifyWithECDsaSecp256r1` syscall.
|
||||
func ECDsaSecp256r1Verify(msg []byte, pub []byte, sig []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ECDsaSecp256k1Verify checks that sig is correct msg's signature for a given pub
|
||||
// (serialized public key). It uses `Neo.Crypto.VerifyWithECDsaSecp256k1` syscall.
|
||||
func ECDsaSecp256k1Verify(msg []byte, pub []byte, sig []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once. It uses
|
||||
// `Neo.Crypto.CheckMultisigWithECDsaSecp256r1` syscall.
|
||||
func ECDSASecp256r1CheckMultisig(msg []byte, pubs [][]byte, sigs [][]byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once. It uses
|
||||
// `Neo.Crypto.CheckMultisigWithECDsaSecp256k1` syscall.
|
||||
func ECDSASecp256k1CheckMultisig(msg []byte, pubs [][]byte, sigs [][]byte) bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ type rpcTestCase struct {
|
|||
}
|
||||
|
||||
const testContractHash = "10e262ef80c76bdecca287a2c047841fc02c3129"
|
||||
const deploymentTxHash = "4843700d16be3e6507a25909d3b2aa1472dcd0526be2520f2bfdd53d768bfebf"
|
||||
const deploymentTxHash = "49f555734b90eb7d4f87041b5146a9b6bc7cf70060bb665212773719091b3a81"
|
||||
|
||||
var rpcTestCases = map[string][]rpcTestCase{
|
||||
"getapplicationlog": {
|
||||
|
@ -720,7 +720,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"sendrawtransaction": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["000a000000316e851039019d39dfc2c37d6c3fee19fd58098780969800000000009269130000000000b00400000001316e851039019d39dfc2c37d6c3fee19fd580987015d0300e87648170000000c1420728274afafc36f43a071d328cfa3e629d9cbb00c14316e851039019d39dfc2c37d6c3fee19fd58098713c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c4037c8c002c3352329c5f2995567a355d57372447c156ea544844d5f8027babf4cd86142d986681992805e3f62f2625b551f18cf05897e6ea7c135f22537bb740e290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
|
||||
params: `["000a000000aa8acf859d4fe402b34e673f2156821796a488eb80969800000000009269130000000000b00400000001aa8acf859d4fe402b34e673f2156821796a488eb015d0300e87648170000000c1478ba4c24009fe510e136c9995a2e05215e1be4dc0c14aa8acf859d4fe402b34e673f2156821796a488eb13c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c4040719393aa590d962cb5a48e16360ac75a6c358c9699e9f1a853afede4d601b6783e28f5ec74542aaf59519e76830ba9d267656db324461fdb08d1d51521e103290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
v := true
|
||||
return &v
|
||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -30,7 +30,7 @@ func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, erro
|
|||
}
|
||||
emit.Int(buf.BinWriter, int64(len(publicKeys)))
|
||||
emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
|
||||
emit.Syscall(buf.BinWriter, "Neo.Crypto.ECDsaCheckMultiSig")
|
||||
emit.Syscall(buf.BinWriter, "Neo.Crypto.CheckMultisigWithECDsaSecp256r1")
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -34,5 +34,5 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
|
|||
assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB()))
|
||||
assert.Equal(t, opcode.PUSHNULL, opcode.Opcode(br.ReadB()))
|
||||
assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB()))
|
||||
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig")), br.ReadU32LE())
|
||||
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")), br.ReadU32LE())
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
verifyInteropID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
|
||||
multisigInteropID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
|
||||
verifyInteropID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))
|
||||
multisigInteropID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1"))
|
||||
)
|
||||
|
||||
func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) {
|
||||
|
|
19
pkg/vm/vm.go
19
pkg/vm/vm.go
|
@ -1,6 +1,7 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -1457,9 +1458,9 @@ func (v *VM) calcJumpOffset(ctx *Context, parameter []byte) (int, int, error) {
|
|||
}
|
||||
|
||||
// CheckMultisigPar checks if sigs contains sufficient valid signatures.
|
||||
func CheckMultisigPar(v *VM, h []byte, pkeys [][]byte, sigs [][]byte) bool {
|
||||
func CheckMultisigPar(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sigs [][]byte) bool {
|
||||
if len(sigs) == 1 {
|
||||
return checkMultisig1(v, h, pkeys, sigs[0])
|
||||
return checkMultisig1(v, curve, h, pkeys, sigs[0])
|
||||
}
|
||||
|
||||
k1, k2 := 0, len(pkeys)-1
|
||||
|
@ -1496,8 +1497,8 @@ func CheckMultisigPar(v *VM, h []byte, pkeys [][]byte, sigs [][]byte) bool {
|
|||
go worker(tasks, results)
|
||||
}
|
||||
|
||||
tasks <- task{pub: v.bytesToPublicKey(pkeys[k1]), signum: s1}
|
||||
tasks <- task{pub: v.bytesToPublicKey(pkeys[k2]), signum: s2}
|
||||
tasks <- task{pub: v.bytesToPublicKey(pkeys[k1], curve), signum: s1}
|
||||
tasks <- task{pub: v.bytesToPublicKey(pkeys[k2], curve), signum: s2}
|
||||
|
||||
sigok := true
|
||||
taskCount := 2
|
||||
|
@ -1541,7 +1542,7 @@ loop:
|
|||
nextKey = k2
|
||||
}
|
||||
taskCount++
|
||||
tasks <- task{pub: v.bytesToPublicKey(pkeys[nextKey]), signum: nextSig}
|
||||
tasks <- task{pub: v.bytesToPublicKey(pkeys[nextKey], curve), signum: nextSig}
|
||||
}
|
||||
|
||||
close(tasks)
|
||||
|
@ -1549,9 +1550,9 @@ loop:
|
|||
return sigok
|
||||
}
|
||||
|
||||
func checkMultisig1(v *VM, h []byte, pkeys [][]byte, sig []byte) bool {
|
||||
func checkMultisig1(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sig []byte) bool {
|
||||
for i := range pkeys {
|
||||
pkey := v.bytesToPublicKey(pkeys[i])
|
||||
pkey := v.bytesToPublicKey(pkeys[i], curve)
|
||||
if pkey.Verify(sig, h) {
|
||||
return true
|
||||
}
|
||||
|
@ -1606,14 +1607,14 @@ func (v *VM) checkInvocationStackSize() {
|
|||
|
||||
// bytesToPublicKey is a helper deserializing keys using cache and panicing on
|
||||
// error.
|
||||
func (v *VM) bytesToPublicKey(b []byte) *keys.PublicKey {
|
||||
func (v *VM) bytesToPublicKey(b []byte, curve elliptic.Curve) *keys.PublicKey {
|
||||
var pkey *keys.PublicKey
|
||||
s := string(b)
|
||||
if v.keys[s] != nil {
|
||||
pkey = v.keys[s]
|
||||
} else {
|
||||
var err error
|
||||
pkey, err = keys.NewPublicKeyFromBytes(b)
|
||||
pkey, err = keys.NewPublicKeyFromBytes(b, curve)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package vm
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/elliptic"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
@ -116,9 +117,9 @@ func TestBytesToPublicKey(t *testing.T) {
|
|||
assert.Equal(t, 0, len(cache))
|
||||
keyHex := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
|
||||
keyBytes, _ := hex.DecodeString(keyHex)
|
||||
key := v.bytesToPublicKey(keyBytes)
|
||||
key := v.bytesToPublicKey(keyBytes, elliptic.P256())
|
||||
assert.NotNil(t, key)
|
||||
key2 := v.bytesToPublicKey(keyBytes)
|
||||
key2 := v.bytesToPublicKey(keyBytes, elliptic.P256())
|
||||
assert.Equal(t, key, key2)
|
||||
|
||||
cache = v.GetPublicKeys()
|
||||
|
@ -126,7 +127,7 @@ func TestBytesToPublicKey(t *testing.T) {
|
|||
assert.NotNil(t, cache[string(keyBytes)])
|
||||
|
||||
keyBytes[0] = 0xff
|
||||
require.Panics(t, func() { v.bytesToPublicKey(keyBytes) })
|
||||
require.Panics(t, func() { v.bytesToPublicKey(keyBytes, elliptic.P256()) })
|
||||
}
|
||||
|
||||
func TestPushBytes1to75(t *testing.T) {
|
||||
|
|
|
@ -113,13 +113,13 @@ func TestAccount_ConvertMultisig(t *testing.T) {
|
|||
t.Run("1/1 multisig", func(t *testing.T) {
|
||||
pubs := convertPubs(t, hexs[:1])
|
||||
require.NoError(t, a.ConvertMultisig(1, pubs))
|
||||
require.Equal(t, "NYqxsNMHxDg3T19APYP27mBZFfauC4zngR", a.Address)
|
||||
require.Equal(t, "NVNvVRW5Q5naSx2k2iZm7xRgtRNGuZppAK", a.Address)
|
||||
})
|
||||
|
||||
t.Run("3/4 multisig", func(t *testing.T) {
|
||||
pubs := convertPubs(t, hexs)
|
||||
require.NoError(t, a.ConvertMultisig(3, pubs))
|
||||
require.Equal(t, "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2", a.Address)
|
||||
require.Equal(t, "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY", a.Address)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
12
pkg/wallet/testdata/wallet1.json
vendored
12
pkg/wallet/testdata/wallet1.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
18
pkg/wallet/testdata/wallet2.json
vendored
18
pkg/wallet/testdata/wallet2.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "3.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
|
||||
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
|
||||
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
|
||||
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
|
||||
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
|
||||
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -44,11 +44,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ",
|
||||
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
|
||||
"address": "NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5",
|
||||
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQQqQatQ=",
|
||||
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQZVEDXg=",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -181,14 +181,14 @@ func TestWalletGetChangeAddress(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
sh := w1.GetChangeAddress()
|
||||
// No default address, the first one is used.
|
||||
expected, err := address.StringToUint160("NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN")
|
||||
expected, err := address.StringToUint160("NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, sh)
|
||||
w2, err := NewWalletFromFile("testdata/wallet2.json")
|
||||
require.NoError(t, err)
|
||||
sh = w2.GetChangeAddress()
|
||||
// Default address.
|
||||
expected, err = address.StringToUint160("NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ")
|
||||
expected, err = address.StringToUint160("NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, sh)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue