Merge pull request #869 from nspcc-dev/neo3/newscript
core: change verification scripts to new format
This commit is contained in:
commit
591a1b900d
35 changed files with 1023 additions and 653 deletions
|
@ -1 +1,56 @@
|
|||
{"name":"wallet1","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet1",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "4c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc250680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
|
@ -1 +1,74 @@
|
|||
{"name":"wallet1","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null},{"address":"AbU69m8WUZJSWanfr1Cy66cpEcsmMcX7BR","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"512102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc251ae","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet1",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y",
|
||||
"contract": {
|
||||
"script": "2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2ac",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y",
|
||||
"contract": {
|
||||
"script": "532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AKJbsdaKKhF8f922EpwKiZNbo8F2mocqHo",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y",
|
||||
"contract": {
|
||||
"script": "514c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995150683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
||||
|
|
|
@ -1 +1,56 @@
|
|||
{"name":"wallet2","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17","label":null,"isDefault":false,"lock":false,"key":"6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L","contract":{"script":"2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406eac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet2",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AdB6ayKfBRJZasiXX4JL5N2YtmxftNp1b3",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYXPEFeBxeDjqMiwRrSe81LnpL1cpw1WSwENJY1p4NtgSbfZPaUFy8Kkg",
|
||||
"contract": {
|
||||
"script": "4c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e50680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYXPEFeBxeDjqMiwRrSe81LnpL1cpw1WSwENJY1p4NtgSbfZPaUFy8Kkg",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
|
@ -1 +1,56 @@
|
|||
{"name":"wallet3","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AR3uEnLUdfm1tPMJmiJQurAXGL7h3EXQ2F","label":null,"isDefault":false,"lock":false,"key":"6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh","contract":{"script":"2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet3",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AbJTkhSMjJnm2CHZbCUe5j8w2xzjDbeWM8",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYRHjZrvxYqrHLpXz1aP6dBnrFkkxQMCdYsJi7YDPoQnQddvRuTzKGxME",
|
||||
"contract": {
|
||||
"script": "4c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69950680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYRHjZrvxYqrHLpXz1aP6dBnrFkkxQMCdYsJi7YDPoQnQddvRuTzKGxME",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
|
@ -1 +1,56 @@
|
|||
{"name":"wallet4","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AJmjUqf1jDenxYpuNS4i2NxD9FQYieDpBF","label":null,"isDefault":false,"lock":false,"key":"6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc","contract":{"script":"2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet4",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AT7C1Jno1CtJTYzA6MH8HpfYYso1RiES8q",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYWscJHQ76uctwuM7GRcAp6xfGjdYDKnbMtMnT6hcXxcNn7CywbQmvfSy",
|
||||
"contract": {
|
||||
"script": "4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd6250680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYWscJHQ76uctwuM7GRcAp6xfGjdYDKnbMtMnT6hcXxcNn7CywbQmvfSy",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
|
@ -2,6 +2,7 @@ package consensus
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
|
@ -348,7 +349,9 @@ func (s *service) verifyBlock(b block.Block) bool {
|
|||
coreb := &b.(*neoBlock).Block
|
||||
for _, tx := range coreb.Transactions {
|
||||
if err := s.Chain.VerifyTx(tx, coreb); err != nil {
|
||||
s.log.Warn("invalid transaction in proposed block", zap.Stringer("hash", tx.Hash()))
|
||||
s.log.Warn("invalid transaction in proposed block",
|
||||
zap.Stringer("hash", tx.Hash()),
|
||||
zap.Error(err))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -462,6 +465,8 @@ func (s *service) getVerifiedTx(count int) []block.Transaction {
|
|||
for {
|
||||
minerTx := transaction.NewMinerTX()
|
||||
minerTx.Outputs = txOuts
|
||||
minerTx.ValidUntilBlock = s.dbft.BlockIndex
|
||||
minerTx.Nonce = rand.Uint32()
|
||||
res[0] = minerTx
|
||||
|
||||
if tx, _, _ := s.Chain.GetTransaction(res[0].Hash()); tx == nil {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package consensus
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/dbft/block"
|
||||
|
@ -9,7 +11,10 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"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/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -195,25 +200,33 @@ func newTestService(t *testing.T) *service {
|
|||
return srv.(*service)
|
||||
}
|
||||
|
||||
func TestExport(t *testing.T) {
|
||||
_, pub := getTestValidator(3)
|
||||
s, _ := smartcontract.CreateMultiSigRedeemScript(1, keys.PublicKeys{pub.PublicKey})
|
||||
fmt.Println(hex.EncodeToString(s))
|
||||
u := hash.Hash160(s)
|
||||
fmt.Println(address.Uint160ToString(u))
|
||||
}
|
||||
|
||||
func getTestValidator(i int) (*privateKey, *publicKey) {
|
||||
var wif, password string
|
||||
|
||||
// Sorted by public key.
|
||||
switch i {
|
||||
case 0:
|
||||
wif = "6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L"
|
||||
wif = "6PYXPEFeBxeDjqMiwRrSe81LnpL1cpw1WSwENJY1p4NtgSbfZPaUFy8Kkg"
|
||||
password = "two"
|
||||
|
||||
case 1:
|
||||
wif = "6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc"
|
||||
wif = "6PYWscJHQ76uctwuM7GRcAp6xfGjdYDKnbMtMnT6hcXxcNn7CywbQmvfSy"
|
||||
password = "four"
|
||||
|
||||
case 2:
|
||||
wif = "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y"
|
||||
wif = "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN"
|
||||
password = "one"
|
||||
|
||||
case 3:
|
||||
wif = "6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh"
|
||||
wif = "6PYRHjZrvxYqrHLpXz1aP6dBnrFkkxQMCdYsJi7YDPoQnQddvRuTzKGxME"
|
||||
password = "three"
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package consensus
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/dbft/payload"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
|
||||
"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/io"
|
||||
|
@ -210,9 +211,7 @@ func (p *Payload) Verify(scriptHash util.Uint160) bool {
|
|||
}
|
||||
|
||||
v := vm.New()
|
||||
h := sha256.Sum256(p.GetSignedPart())
|
||||
|
||||
v.SetCheckedHash(h[:])
|
||||
v.RegisterInteropGetter(crypto.GetInterop(&interop.Context{Container: p}))
|
||||
v.LoadScript(verification)
|
||||
v.LoadScript(p.Witness.InvocationScript)
|
||||
|
||||
|
|
57
pkg/consensus/testdata/wallet1.json
vendored
57
pkg/consensus/testdata/wallet1.json
vendored
|
@ -1 +1,56 @@
|
|||
{"name":"wallet1","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet1",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "4c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc250680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
57
pkg/consensus/testdata/wallet2.json
vendored
57
pkg/consensus/testdata/wallet2.json
vendored
|
@ -1 +1,56 @@
|
|||
{"name":"wallet2","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17","label":null,"isDefault":false,"lock":false,"key":"6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L","contract":{"script":"2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406eac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet2",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AdB6ayKfBRJZasiXX4JL5N2YtmxftNp1b3",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYXPEFeBxeDjqMiwRrSe81LnpL1cpw1WSwENJY1p4NtgSbfZPaUFy8Kkg",
|
||||
"contract": {
|
||||
"script": "4c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e50680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYXPEFeBxeDjqMiwRrSe81LnpL1cpw1WSwENJY1p4NtgSbfZPaUFy8Kkg",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
57
pkg/consensus/testdata/wallet3.json
vendored
57
pkg/consensus/testdata/wallet3.json
vendored
|
@ -1 +1,56 @@
|
|||
{"name":"wallet3","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AR3uEnLUdfm1tPMJmiJQurAXGL7h3EXQ2F","label":null,"isDefault":false,"lock":false,"key":"6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh","contract":{"script":"2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet3",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AbJTkhSMjJnm2CHZbCUe5j8w2xzjDbeWM8",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYRHjZrvxYqrHLpXz1aP6dBnrFkkxQMCdYsJi7YDPoQnQddvRuTzKGxME",
|
||||
"contract": {
|
||||
"script": "4c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69950680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYRHjZrvxYqrHLpXz1aP6dBnrFkkxQMCdYsJi7YDPoQnQddvRuTzKGxME",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
57
pkg/consensus/testdata/wallet4.json
vendored
57
pkg/consensus/testdata/wallet4.json
vendored
|
@ -1 +1,56 @@
|
|||
{"name":"wallet4","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AJmjUqf1jDenxYpuNS4i2NxD9FQYieDpBF","label":null,"isDefault":false,"lock":false,"key":"6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc","contract":{"script":"2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet4",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AT7C1Jno1CtJTYzA6MH8HpfYYso1RiES8q",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYWscJHQ76uctwuM7GRcAp6xfGjdYDKnbMtMnT6hcXxcNn7CywbQmvfSy",
|
||||
"contract": {
|
||||
"script": "4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd6250680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYWscJHQ76uctwuM7GRcAp6xfGjdYDKnbMtMnT6hcXxcNn7CywbQmvfSy",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
|
@ -668,7 +668,6 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
|||
case *transaction.InvocationTX:
|
||||
systemInterop := bc.newInteropContext(trigger.Application, cache, block, tx)
|
||||
v := SpawnVM(systemInterop)
|
||||
v.SetCheckedHash(tx.VerificationHash().BytesBE())
|
||||
v.LoadScript(t.Script)
|
||||
v.SetPriceGetter(getPrice)
|
||||
if bc.config.FreeGasLimit > 0 {
|
||||
|
@ -1956,14 +1955,13 @@ func ScriptFromWitness(hash util.Uint160, witness *transaction.Witness) ([]byte,
|
|||
}
|
||||
|
||||
// verifyHashAgainstScript verifies given hash against the given witness.
|
||||
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, checkedHash util.Uint256, interopCtx *interop.Context, useKeys bool) error {
|
||||
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, interopCtx *interop.Context, useKeys bool) error {
|
||||
verification, err := ScriptFromWitness(hash, witness)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vm := SpawnVM(interopCtx)
|
||||
vm.SetCheckedHash(checkedHash.BytesBE())
|
||||
vm.LoadScript(verification)
|
||||
vm.LoadScript(witness.InvocationScript)
|
||||
if useKeys {
|
||||
|
@ -2023,7 +2021,7 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block
|
|||
sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) })
|
||||
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, block, t)
|
||||
for i := 0; i < len(hashes); i++ {
|
||||
err := bc.verifyHashAgainstScript(hashes[i], &witnesses[i], t.VerificationHash(), interopCtx, false)
|
||||
err := bc.verifyHashAgainstScript(hashes[i], &witnesses[i], interopCtx, false)
|
||||
if err != nil {
|
||||
numStr := fmt.Sprintf("witness #%d", i)
|
||||
return errors.Wrap(err, numStr)
|
||||
|
@ -2042,7 +2040,8 @@ func (bc *Blockchain) verifyHeaderWitnesses(currHeader, prevHeader *block.Header
|
|||
hash = prevHeader.NextConsensus
|
||||
}
|
||||
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, nil, nil)
|
||||
return bc.verifyHashAgainstScript(hash, &currHeader.Script, currHeader.VerificationHash(), interopCtx, true)
|
||||
interopCtx.Container = currHeader
|
||||
return bc.verifyHashAgainstScript(hash, &currHeader.Script, interopCtx, true)
|
||||
}
|
||||
|
||||
func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
|
||||
|
|
|
@ -29,29 +29,6 @@ func getPrice(v *vm.VM, op opcode.Opcode, parameter []byte) util.Fixed8 {
|
|||
return toFixed8(10)
|
||||
case opcode.HASH160, opcode.HASH256:
|
||||
return toFixed8(20)
|
||||
case opcode.CHECKSIG, opcode.VERIFY:
|
||||
return toFixed8(100)
|
||||
case opcode.CHECKMULTISIG:
|
||||
estack := v.Estack()
|
||||
if estack.Len() == 0 {
|
||||
return toFixed8(1)
|
||||
}
|
||||
|
||||
var cost int
|
||||
|
||||
item := estack.Peek(0)
|
||||
switch item.Item().(type) {
|
||||
case *vm.ArrayItem, *vm.StructItem:
|
||||
cost = len(item.Array())
|
||||
default:
|
||||
cost = int(item.BigInt().Int64())
|
||||
}
|
||||
|
||||
if cost < 1 {
|
||||
return toFixed8(1)
|
||||
}
|
||||
|
||||
return toFixed8(int64(100 * cost))
|
||||
default:
|
||||
return toFixed8(1)
|
||||
}
|
||||
|
|
|
@ -208,7 +208,7 @@ func TestCreateBasicChain(t *testing.T) {
|
|||
})
|
||||
|
||||
// multisig address which possess all NEO
|
||||
scriptHash, err := util.Uint160DecodeStringBE("be48d3a3f5d10013ab9ffee489706078714f1ea2")
|
||||
scriptHash, err := util.Uint160DecodeStringBE("d60ac443bb800fb08261e75fa5925d747d485861")
|
||||
require.NoError(t, err)
|
||||
priv0, err := keys.NewPrivateKeyFromWIF(privNetKeys[0])
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -43,8 +43,7 @@ func ECDSACheckMultisig(ic *interop.Context, v *vm.VM) error {
|
|||
if len(pkeys) < len(sigs) {
|
||||
return errors.New("more signatures than there are keys")
|
||||
}
|
||||
v.SetCheckedHash(hashToCheck)
|
||||
sigok := vm.CheckMultisigPar(v, pkeys, sigs)
|
||||
sigok := vm.CheckMultisigPar(v, hashToCheck, pkeys, sigs)
|
||||
v.Estack().PushVal(sigok)
|
||||
return nil
|
||||
}
|
||||
|
|
110
pkg/core/interop/crypto/ecdsa_test.go
Normal file
110
pkg/core/interop/crypto/ecdsa_test.go
Normal file
|
@ -0,0 +1,110 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func initCHECKMULTISIG(msg []byte, n int) ([]vm.StackItem, []vm.StackItem, map[string]*keys.PublicKey, error) {
|
||||
var err error
|
||||
|
||||
keyMap := make(map[string]*keys.PublicKey)
|
||||
pkeys := make([]*keys.PrivateKey, n)
|
||||
pubs := make([]vm.StackItem, n)
|
||||
for i := range pubs {
|
||||
pkeys[i], err = keys.NewPrivateKey()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
pk := pkeys[i].PublicKey()
|
||||
data := pk.Bytes()
|
||||
pubs[i] = vm.NewByteArrayItem(data)
|
||||
keyMap[string(data)] = pk
|
||||
}
|
||||
|
||||
sigs := make([]vm.StackItem, n)
|
||||
for i := range sigs {
|
||||
sig := pkeys[i].Sign(msg)
|
||||
sigs[i] = vm.NewByteArrayItem(sig)
|
||||
}
|
||||
|
||||
return pubs, sigs, keyMap, nil
|
||||
}
|
||||
|
||||
func subSlice(arr []vm.StackItem, indices []int) []vm.StackItem {
|
||||
if indices == nil {
|
||||
return arr
|
||||
}
|
||||
|
||||
result := make([]vm.StackItem, len(indices))
|
||||
for i, j := range indices {
|
||||
result[i] = arr[j]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
v := vm.New()
|
||||
ic := &interop.Context{Trigger: trigger.Verification}
|
||||
v.RegisterInteropGetter(GetInterop(ic))
|
||||
v.LoadScript(buf)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
|
||||
pubs, sigs, _, err := initCHECKMULTISIG(msg, n)
|
||||
require.NoError(t, err)
|
||||
|
||||
pubs = subSlice(pubs, ik)
|
||||
sigs = subSlice(sigs, is)
|
||||
|
||||
v.Estack().PushVal(sigs)
|
||||
v.Estack().PushVal(pubs)
|
||||
v.Estack().PushVal(msg)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func testCHECKMULTISIGGood(t *testing.T, n int, is []int) {
|
||||
v := initCHECKMULTISIGVM(t, n, nil, is)
|
||||
|
||||
require.NoError(t, v.Run())
|
||||
assert.Equal(t, 1, v.Estack().Len())
|
||||
assert.True(t, v.Estack().Pop().Bool())
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGGood(t *testing.T) {
|
||||
t.Run("3_1", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{1}) })
|
||||
t.Run("2_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 2, []int{0, 1}) })
|
||||
t.Run("3_3", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{0, 1, 2}) })
|
||||
t.Run("3_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{0, 2}) })
|
||||
t.Run("4_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 4, []int{0, 2}) })
|
||||
t.Run("10_7", func(t *testing.T) { testCHECKMULTISIGGood(t, 10, []int{2, 3, 4, 5, 6, 8, 9}) })
|
||||
t.Run("12_9", func(t *testing.T) { testCHECKMULTISIGGood(t, 12, []int{0, 1, 4, 5, 6, 7, 8, 9}) })
|
||||
}
|
||||
|
||||
func testCHECKMULTISIGBad(t *testing.T, n int, ik, is []int) {
|
||||
v := initCHECKMULTISIGVM(t, n, ik, is)
|
||||
|
||||
require.NoError(t, v.Run())
|
||||
assert.Equal(t, 1, v.Estack().Len())
|
||||
assert.False(t, v.Estack().Pop().Bool())
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGBad(t *testing.T) {
|
||||
t.Run("1_1 wrong signature", func(t *testing.T) { testCHECKMULTISIGBad(t, 2, []int{0}, []int{1}) })
|
||||
t.Run("3_2 wrong order", func(t *testing.T) { testCHECKMULTISIGBad(t, 3, []int{0, 2}, []int{2, 0}) })
|
||||
t.Run("3_2 duplicate sig", func(t *testing.T) { testCHECKMULTISIGBad(t, 3, nil, []int{0, 0}) })
|
||||
}
|
34
pkg/core/interop/crypto/interop.go
Normal file
34
pkg/core/interop/crypto/interop.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
)
|
||||
|
||||
var (
|
||||
ecdsaVerifyID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
|
||||
ecdsaCheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
|
||||
)
|
||||
|
||||
// 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:
|
||||
return &vm.InteropFuncPrice{
|
||||
Func: func(v *vm.VM) error {
|
||||
return ECDSAVerify(ic, v)
|
||||
},
|
||||
}
|
||||
case ecdsaCheckMultisigID:
|
||||
return &vm.InteropFuncPrice{
|
||||
Func: func(v *vm.VM) error {
|
||||
return ECDSACheckMultisig(ic, v)
|
||||
},
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,14 +20,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 := "cf98b48f81ce3162cdd0883bb0c4cbf3abc105623ba7a61133a776c1e33a2466"
|
||||
expect := "75b6219158953816fbfe1884160f3fe0a4a4d0f7a2b7948bc89787d616f84983"
|
||||
assert.Equal(t, expect, block.Hash().StringLE())
|
||||
}
|
||||
|
||||
func TestGetConsensusAddressMainNet(t *testing.T) {
|
||||
var (
|
||||
consensusAddr = "APyEx5f4Zm4oCHwFWiSTaph1fPBxZacYVR"
|
||||
consensusScript = "59e75d652b5d3827bf04c165bbe9ef95cca4bf55"
|
||||
consensusAddr = "ASwdHjdAGfmSDuZbr641W1eYFVugjByJAS"
|
||||
consensusScript = "7a818ecc4582f8526e7c4271a690c04bd3b9e017"
|
||||
)
|
||||
|
||||
cfg, err := config.Load("../../config", config.ModeMainNet)
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -230,10 +231,13 @@ func (p *PublicKey) EncodeBinary(w *io.BinWriter) {
|
|||
// public key.
|
||||
func (p *PublicKey) GetVerificationScript() []byte {
|
||||
b := p.Bytes()
|
||||
b = append([]byte{byte(opcode.PUSHBYTES33)}, b...)
|
||||
b = append(b, byte(opcode.CHECKSIG))
|
||||
buf := io.NewBufBinWriter()
|
||||
emit.Instruction(buf.BinWriter, opcode.PUSHDATA1, []byte{33})
|
||||
buf.BinWriter.WriteBytes(b)
|
||||
emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
|
||||
emit.Syscall(buf.BinWriter, "Neo.Crypto.ECDsaVerify")
|
||||
|
||||
return b
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// GetScriptHash returns a Hash160 of verification script for the key.
|
||||
|
|
|
@ -89,7 +89,7 @@ func TestPubkeyToAddress(t *testing.T) {
|
|||
pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
|
||||
require.NoError(t, err)
|
||||
actual := pubKey.Address()
|
||||
expected := "AUpGsNCHzSimeMRVPQfhwrVdiUp8Q2N2Qx"
|
||||
expected := "Ads7RRw2vS2jfRypVbMUGt22pxaDaojJHs"
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,28 +14,28 @@ type Ktype struct {
|
|||
// Arr contains a set of known keys in Ktype format.
|
||||
var Arr = []Ktype{
|
||||
{
|
||||
Address: "ALq7AWrhAueN6mJNqk6FHJjnsEoPRytLdW",
|
||||
Address: "Ac5bo2k5rKFvYzCZaTqUG6xFe6iXuW9xQs",
|
||||
PrivateKey: "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344",
|
||||
PublicKey: "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef",
|
||||
Wif: "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g",
|
||||
Passphrase: "city of zion",
|
||||
EncryptedWif: "6PYLHmDf6AjF4AsVtosmxHuPYeuyJL3SLuw7J1U8i7HxKAnYNsp61HYRfF",
|
||||
EncryptedWif: "6PYKSxMYzHGuiT3iK7kkeGqn3Q6hJnHUc3U3Hro2kb1rPC7G15Eg2GnqL7",
|
||||
},
|
||||
{
|
||||
Address: "ALfnhLg7rUyL6Jr98bzzoxz5J7m64fbR4s",
|
||||
Address: "ATKoxGh7rytJRr96XWkvs3shMM5uiiHjhg",
|
||||
PrivateKey: "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69",
|
||||
PublicKey: "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9",
|
||||
Wif: "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG",
|
||||
Passphrase: "我的密码",
|
||||
EncryptedWif: "6PYWVp3xfgvnuNKP7ZavSViYvvim2zuzx9Q33vuWZr8aURiKeJ6Zm7BfPQ",
|
||||
EncryptedWif: "6PYQYBtL2kifXe3Dv96pMoPNJ2fZz8cPv2YqpHGKdfM2g5swEBUdwJqKsu",
|
||||
},
|
||||
{
|
||||
Address: "AVf4UGKevVrMR1j3UkPsuoYKSC4ocoAkKx",
|
||||
Address: "AbjLAUABpmvLAJv4brQ7pt4QG87qy8K75T",
|
||||
PrivateKey: "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b",
|
||||
PublicKey: "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
|
||||
Wif: "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
|
||||
Passphrase: "MyL33tP@33w0rd",
|
||||
EncryptedWif: "6PYNoc1EG5J38MTqGN9Anphfdd6UwbS4cpFCzHhrkSKBBbV1qkbJJZQnkn",
|
||||
EncryptedWif: "6PYMbnB7h7SjueFXUMUiGptmvMXZKLALSsCnuaotBEAnmv5fXiYh7vReBA",
|
||||
},
|
||||
{
|
||||
Address: "xdf4UGKevVrMR1j3UkPsuoYKSC4ocoAkKx",
|
||||
|
@ -43,7 +43,7 @@ var Arr = []Ktype{
|
|||
PublicKey: "zz232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
|
||||
Wif: "zzKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
|
||||
Passphrase: "zzL33tP@33w0rd",
|
||||
EncryptedWif: "6PYNoc1EG5J38MTqGN9Anphfdd6UwbS4cpFCzHhrkSKBBbV1qkbJJZQnkn",
|
||||
EncryptedWif: "6PYMbnB7h7SjueFXUMUiGptmvMXZKLALSsCnuaotBEAnmv5fXiYh7vReBA",
|
||||
Invalid: true,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -49,14 +49,14 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"getapplicationlog": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["d98e4b58783aa9665efcc5be19ee432772a94462efc8a5e4165776e6dd8c4e92"]`,
|
||||
params: `["a62dccca145b9df9793ddbe80fd96fd6360403c52926909b9e6fd9a4ac5549aa"]`,
|
||||
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.ApplicationLog)
|
||||
|
||||
require.True(t, ok)
|
||||
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("d98e4b58783aa9665efcc5be19ee432772a94462efc8a5e4165776e6dd8c4e92")
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("a62dccca145b9df9793ddbe80fd96fd6360403c52926909b9e6fd9a4ac5549aa")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedTxHash, res.TxHash)
|
||||
assert.Equal(t, 1, len(res.Executions))
|
||||
|
@ -88,7 +88,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"getaccountstate": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU"]`,
|
||||
params: `["AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6"]`,
|
||||
result: func(e *executor) interface{} { return &result.AccountState{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.AccountState)
|
||||
|
@ -162,12 +162,12 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "positive",
|
||||
params: `["a90f00d94349a320376b7cb86c884b53ad76aa2b"]`,
|
||||
params: `["c4bba7ed4e624d038b844d6b6ff24518e7db0165"]`,
|
||||
result: func(e *executor) interface{} { return &result.NEP5Balances{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.NEP5Balances)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs", res.Address)
|
||||
require.Equal(t, "AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY", res.Address)
|
||||
require.Equal(t, 1, len(res.Balances))
|
||||
require.Equal(t, "8.77", res.Balances[0].Amount)
|
||||
require.Equal(t, testContractHash, res.Balances[0].Asset.StringLE())
|
||||
|
@ -188,12 +188,12 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "positive",
|
||||
params: `["AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs"]`,
|
||||
params: `["AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY"]`,
|
||||
result: func(e *executor) interface{} { return &result.NEP5Transfers{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.NEP5Transfers)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs", res.Address)
|
||||
require.Equal(t, "AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY", res.Address)
|
||||
|
||||
assetHash, err := util.Uint160DecodeStringLE(testContractHash)
|
||||
require.NoError(t, err)
|
||||
|
@ -206,7 +206,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
require.Equal(t, 1, len(res.Sent))
|
||||
require.Equal(t, "1.23", res.Sent[0].Amount)
|
||||
require.Equal(t, assetHash, res.Sent[0].Asset)
|
||||
require.Equal(t, "AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17", res.Sent[0].Address)
|
||||
require.Equal(t, "AdB6ayKfBRJZasiXX4JL5N2YtmxftNp1b3", res.Sent[0].Address)
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -405,25 +405,25 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"getblockheader": {
|
||||
{
|
||||
name: "positive, no verbose",
|
||||
params: `["60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608"]`,
|
||||
params: `["26d52a2541614f8639bc030493c4f2be2003094bbba2219aee3e097beb730a8d"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
expected := "000000009456b8c7f89bdfe012a30a2be9af5218e048ae7372115ce3e39cc847c01e9e7f9cffa26c112eb147a995520e47afbc45a192d9bf1a8e9b8f80497e5d92c4e9f2011e975e010000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401404be65e52d50121ce243eb27f7a1c16637e753e847e9c027f255bc5e2bae45f1c99d8c1014e5abe829b9a229904540b7010ae6fb2bb57f88d70179ec617dea35440c9d51c5980e016f5cb51734554341764572b0644010952761878b1966d2b013ceaf18958891060dde3a33d23118f27ef21e991f913a8740c716c14aa19483ea0409a44efd5607f7b8f09dd4f242882713b40866c2aeab9aaa5f92b92dbaf84ed0c039fb1790888ab36d77c8b6520b2bb58ab43b219be3272145cf0f6fd091e33e540ec1e52377a56bb6e0f82329ac1a70ab06cb7e23c149bcc194fa483a316de33468191b16ab1fafb2f1a1af79a0cd6e7e275d3a3ed56f8b0ecbcd6e26f93a3957b8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"
|
||||
expected := "000000002f1f4e815a5951622f4c3863d5a27da7819259517971118de2f979d70850c15d4c8edb530dbd32f20674901fea73dd41c6b1af2ab9520b92447460351727be2c28a3995e010000005704000000000000d60ac443bb800fb08261e75fa5925d747d48586101fd040140e87e9ea015e46febb3ef938d7a458b2f70d84eb0584b2b22b0f85ecfe292d98742569d27ef2f4eafca967a9bbbb1e90efe4046d550f821f70fe39cb07aa70b87409d894b16bc8ab1b1edb0e921e0171ea7e8bf713854896eddd9d1bbc8e2ec80df616e30c0518dd3053a8d53464bb5615bd2cc83aca8fb9a8c37a259a30ba9a571405cfbfee1b86d4819c25f6a97374cef09733fc006e73ee18e5ada58d348983e1b753fad166c7220154fe21ca482feccaf1ff1598660ab7bef087ca16325db4ed9403baed63512e0bec4d5afb8c27525951a8855e579530c9ebf5aae4430492a426abb2eac309828c83e1d132bf9334b31d538fde4a2cfdb9e50da16b29db787152c94534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb00"
|
||||
return &expected
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive, verbose 0",
|
||||
params: `["60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608", 0]`,
|
||||
params: `["26d52a2541614f8639bc030493c4f2be2003094bbba2219aee3e097beb730a8d", 0]`,
|
||||
result: func(e *executor) interface{} {
|
||||
expected := "000000009456b8c7f89bdfe012a30a2be9af5218e048ae7372115ce3e39cc847c01e9e7f9cffa26c112eb147a995520e47afbc45a192d9bf1a8e9b8f80497e5d92c4e9f2011e975e010000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401404be65e52d50121ce243eb27f7a1c16637e753e847e9c027f255bc5e2bae45f1c99d8c1014e5abe829b9a229904540b7010ae6fb2bb57f88d70179ec617dea35440c9d51c5980e016f5cb51734554341764572b0644010952761878b1966d2b013ceaf18958891060dde3a33d23118f27ef21e991f913a8740c716c14aa19483ea0409a44efd5607f7b8f09dd4f242882713b40866c2aeab9aaa5f92b92dbaf84ed0c039fb1790888ab36d77c8b6520b2bb58ab43b219be3272145cf0f6fd091e33e540ec1e52377a56bb6e0f82329ac1a70ab06cb7e23c149bcc194fa483a316de33468191b16ab1fafb2f1a1af79a0cd6e7e275d3a3ed56f8b0ecbcd6e26f93a3957b8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"
|
||||
expected := "000000002f1f4e815a5951622f4c3863d5a27da7819259517971118de2f979d70850c15d4c8edb530dbd32f20674901fea73dd41c6b1af2ab9520b92447460351727be2c28a3995e010000005704000000000000d60ac443bb800fb08261e75fa5925d747d48586101fd040140e87e9ea015e46febb3ef938d7a458b2f70d84eb0584b2b22b0f85ecfe292d98742569d27ef2f4eafca967a9bbbb1e90efe4046d550f821f70fe39cb07aa70b87409d894b16bc8ab1b1edb0e921e0171ea7e8bf713854896eddd9d1bbc8e2ec80df616e30c0518dd3053a8d53464bb5615bd2cc83aca8fb9a8c37a259a30ba9a571405cfbfee1b86d4819c25f6a97374cef09733fc006e73ee18e5ada58d348983e1b753fad166c7220154fe21ca482feccaf1ff1598660ab7bef087ca16325db4ed9403baed63512e0bec4d5afb8c27525951a8855e579530c9ebf5aae4430492a426abb2eac309828c83e1d132bf9334b31d538fde4a2cfdb9e50da16b29db787152c94534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb00"
|
||||
return &expected
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive, verbose !=0",
|
||||
params: `["60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608", 2]`,
|
||||
params: `["26d52a2541614f8639bc030493c4f2be2003094bbba2219aee3e097beb730a8d", 2]`,
|
||||
result: func(e *executor) interface{} {
|
||||
hash, err := util.Uint256DecodeStringLE("60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608")
|
||||
hash, err := util.Uint256DecodeStringLE("26d52a2541614f8639bc030493c4f2be2003094bbba2219aee3e097beb730a8d")
|
||||
if err != nil {
|
||||
panic("can not decode hash parameter")
|
||||
}
|
||||
|
@ -517,10 +517,10 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "normal address",
|
||||
params: `["AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU"]`,
|
||||
params: `["AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6"]`,
|
||||
result: func(*executor) interface{} {
|
||||
// hash of the issueTx
|
||||
h, _ := util.Uint256DecodeStringBE("7b5710faf4ea62e3cd7f526d3dad39e85e1823c62340c88b80e36fd99342457a")
|
||||
h, _ := util.Uint256DecodeStringBE("e9a7882fa874508dff8a3f21d32da2afb9f9d303753953a524c75b81e295c914")
|
||||
amount := util.Fixed8FromInt64(1 * 8) // (endHeight - startHeight) * genAmount[0]
|
||||
return &result.ClaimableInfo{
|
||||
Spents: []result.Claimable{
|
||||
|
@ -532,7 +532,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
Unclaimed: amount,
|
||||
},
|
||||
},
|
||||
Address: "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU",
|
||||
Address: "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
Unclaimed: amount,
|
||||
}
|
||||
},
|
||||
|
@ -579,7 +579,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"gettransactionheight": {
|
||||
{
|
||||
name: "poositive",
|
||||
params: `["2f0ed00979cb5feae842946be2afb96deec9c13236605fda63737db223089a00"]`,
|
||||
params: `["4b0be2562c7f49a496f08eb6983b46904c99dfb7c65d3a32d7b09cbc503a7889"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
h := 1
|
||||
return &h
|
||||
|
@ -614,7 +614,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "positive",
|
||||
params: `["AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU"]`,
|
||||
params: `["AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6"]`,
|
||||
result: func(*executor) interface{} {
|
||||
return &result.Unclaimed{}
|
||||
},
|
||||
|
@ -630,7 +630,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"getunspents": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU"]`,
|
||||
params: `["AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6"]`,
|
||||
result: func(e *executor) interface{} { return &result.Unspents{} },
|
||||
check: func(t *testing.T, e *executor, unsp interface{}) {
|
||||
res, ok := unsp.(*result.Unspents)
|
||||
|
@ -791,7 +791,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"sendrawtransaction": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["800013000000b004000000010655773cea2a4f8cc66f83989605a58e87e885b6aaf58d450db3b83f81a2c950010001a9bf999e43ccfe9d40c3450fc75ca4b02db9b1691a7e1989b331f621456289050030d3dec38623002baa76ad534b886cb87c6b3720a34943d9000fa9014140faa7f2c3f700838aa48be950aff762c050f1cf04f1185fb3893820f63a98ccbfed05e8c5931f67ade59054c853be1d37ff9e75ed65b0543255ff28a3f8667670232102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2ac"]`,
|
||||
params: `["800013000000b004000000013bc3087e4af3b30310500396aa972d7a8ac87a7046dff9dc030e03c2bbc09be9010001a9bf999e43ccfe9d40c3450fc75ca4b02db9b1691a7e1989b331f621456289050030d3dec38623006501dbe71845f26f6b4d848b034d624eeda7bbc40141401026a8d3bd5839d1ead869dcba75dd19c112671d5a86e3443e4fd8c456e8c3fae1ed108065bfe47d62127e33a2419ee1d2140a66712c6ae4b5d2ad0758c5b5dd294c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc250680a906ad4"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
v := true
|
||||
return &v
|
||||
|
@ -822,7 +822,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
{
|
||||
// If you are planning to modify test chain from `testblocks.acc`, please, update param value (first block)
|
||||
name: "empty block",
|
||||
params: `["00000000547e0fa207c116e25fd69a04b99e446e409ca23c7863bafbd585abeb468314c00000000000000000000000000000000000000000000000000000000000000000d21e975ed10000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401404fb770b14c4e7bd2461dbf238ca197844a724388d15cfeb96a07cb8cb52733f3f7adcc5bbd33c8dc19103116f1fe6c3151a14e3db40585823cc3ce153a0426ec40fd880f3d029e95dcb4612b40f31d5111a961345bc2090689a7462c12c85006ed281216331e1169d41cc0a8780b0befc22b9d3ba147e331acfb858675ebaaf8de4055922389015e0a96e07c9ad987eda4a642f0436843966821e620b89bf84e8ec22a33c308ad7e9815b1d0bebd93289db1828bec516d3b2ccfcaf080d2b7ea385f408005e2ff7387c50393407b125a09f42970b4b8033737e0b5ee04c1dfc9e6ad15da879cd46b3177b302ee1c109acbce4af689bb7e89978e4709e97d2db76c7ada8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"]`,
|
||||
params: `["00000000f0fae05006c8c784404415faf69023f9e607f04a1fcfde2a4bd93a8c3fdfd1980000000000000000000000000000000000000000000000000000000000000000f8a3995ed10000005704000000000000d60ac443bb800fb08261e75fa5925d747d48586101fd040140a3f627a07ae219f3dce5525f1b01b913c7dbe9ba6a725bdf49733290e5f3e50f2ba8f434d564ebfaeae40433a4b8746dccb2d4ab36712a87d3600e07548f398140b2e23d220f965736277f509e659f76c8bc376b1b28c3d4c817fbd96ec82eb4e11a5c4fe67b7df6ff8f6efe2a71c3582a7c0403494f84f90c4efc7a314b2c6c8d404f5dcd7ac82e541e7fda965460df0a8563f0ca71c7211263f9dc783a77a6b968bc1f7bf57f34fe48f8978aa94d6c21bcde59bc6dae16eee0d37ec5d8bb0447d240dc6dd5692f1a49862805e18f2a77016ee94e3529cb2856571b9146e53f572fed1c6e31e655b8f94e55a665c25001d3477375db31d6924e88d32ded33a6d6f6cb94534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb00"]`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
|
@ -848,7 +848,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
{
|
||||
name: "positive",
|
||||
// If you are planning to modify test chain from `testblocks.acc`, please, update param value (second block)
|
||||
params: `["00000000547e0fa207c116e25fd69a04b99e446e409ca23c7863bafbd585abeb468314c0980135e10c52e5444c962659b388a5b226114a45d3912a88700ac6b05aaaf961d21e975ed10000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd040140dc1690f42fd67440defaf6385ad5d77b3a2ffba6270c22aa20373eab011cc5eb46e1aeb0f5f9d3f78ebd29d7fb3bb47777e2a0793e4594761e74dc6867834f6a405ebde4af3a4fedefc33c7debf58a159dcd4a66e396c007bf9cc185f422ff449849efcbbb8d772df213b3b412b7ca4188ec3a4ac841c3374ae4cac3277e16d39640ee9e51540a5c37100e0964f279938561096df6693429e692ce39553f63db53ce4f4d4d777e00299c594f7c8095410b03b5ca253f6946e081069180890a443e8e40981c77a1d7a9e9d71e54ba3edd8d740b24b723efefd7eca87ba9e5c2abb2a07dea5ab83e643cabc20af3d2e90990e668973850bd7be723097f34a47ac60fddc28b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae01000014000000b004000000000000"]`,
|
||||
params: `["00000000f0fae05006c8c784404415faf69023f9e607f04a1fcfde2a4bd93a8c3fdfd198980135e10c52e5444c962659b388a5b226114a45d3912a88700ac6b05aaaf961f8a3995ed10000005704000000000000d60ac443bb800fb08261e75fa5925d747d48586101fd0401406413cf294f0506e81b73a8b6f9ecc8d1ac73afc55852ca65ff2dc08ee217425030d8b16ec36d7f7b1111198337185f71ac2b24b9e4ca8806bc2c3ba5f63bf31540f48633e1541acdbdb4509e522b49e4df48b55bc884f5fd5abae014292f74ca7066232967176826fbb0b6919e14b3c9e91b916cb7003c019b8afb42e37cf97e9140d8f44efe93ab380bab8b6fc29e5d8ba1502feda12eb35c9472906e5c46ffdfff56047f383aa87b9724c219eca43d165c31fb246528e410fbcb4a9a04816c77aa40187874fb7193ce5613382e0059f0ff421fc252c31c83e299dfd097a453afb8a65fd95c7711d4d247ad82179e98146338b58864caf8601a6bb7b62300fa9af9e594534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb01000014000000b004000000000000"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
v := true
|
||||
return &v
|
||||
|
@ -975,7 +975,7 @@ func TestRPC(t *testing.T) {
|
|||
assert.Equal(t, 0, txOut.N)
|
||||
assert.Equal(t, "0xa9bf999e43ccfe9d40c3450fc75ca4b02db9b1691a7e1989b331f62145628905", txOut.Asset)
|
||||
assert.Equal(t, util.Fixed8FromInt64(100000000), txOut.Value)
|
||||
assert.Equal(t, "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU", txOut.Address)
|
||||
assert.Equal(t, "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6", txOut.Address)
|
||||
})
|
||||
|
||||
t.Run("getrawmempool", func(t *testing.T) {
|
||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -4,6 +4,8 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
|
||||
|
@ -55,10 +57,7 @@ func TestParameterContext_AddSignatureSimpleContract(t *testing.T) {
|
|||
t.Run("GetWitness", func(t *testing.T) {
|
||||
w, err := c.GetWitness(ctr)
|
||||
require.NoError(t, err)
|
||||
v := vm.New()
|
||||
v.SetCheckedHash(tx.VerificationHash().BytesBE())
|
||||
v.LoadScript(w.VerificationScript)
|
||||
v.LoadScript(w.InvocationScript)
|
||||
v := newTestVM(w, tx)
|
||||
require.NoError(t, v.Run())
|
||||
require.Equal(t, 1, v.Estack().Len())
|
||||
require.Equal(t, true, v.Estack().Pop().Value())
|
||||
|
@ -102,16 +101,21 @@ func TestParameterContext_AddSignatureMultisig(t *testing.T) {
|
|||
t.Run("GetWitness", func(t *testing.T) {
|
||||
w, err := c.GetWitness(ctr)
|
||||
require.NoError(t, err)
|
||||
v := vm.New()
|
||||
v.SetCheckedHash(tx.VerificationHash().BytesBE())
|
||||
v.LoadScript(w.VerificationScript)
|
||||
v.LoadScript(w.InvocationScript)
|
||||
v := newTestVM(w, tx)
|
||||
require.NoError(t, v.Run())
|
||||
require.Equal(t, 1, v.Estack().Len())
|
||||
require.Equal(t, true, v.Estack().Pop().Value())
|
||||
})
|
||||
}
|
||||
|
||||
func newTestVM(w *transaction.Witness, tx *transaction.Transaction) *vm.VM {
|
||||
v := vm.New()
|
||||
v.RegisterInteropGetter(crypto.GetInterop(&interop.Context{Container: tx}))
|
||||
v.LoadScript(w.VerificationScript)
|
||||
v.LoadScript(w.InvocationScript)
|
||||
return v
|
||||
}
|
||||
|
||||
func TestParameterContext_MarshalJSON(t *testing.T) {
|
||||
priv, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -26,10 +26,12 @@ func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, erro
|
|||
emit.Int(buf.BinWriter, int64(m))
|
||||
sort.Sort(publicKeys)
|
||||
for _, pubKey := range publicKeys {
|
||||
emit.Bytes(buf.BinWriter, pubKey.Bytes())
|
||||
emit.Instruction(buf.BinWriter, opcode.PUSHDATA1, []byte{33})
|
||||
buf.BinWriter.WriteBytes(pubKey.Bytes())
|
||||
}
|
||||
emit.Int(buf.BinWriter, int64(len(publicKeys)))
|
||||
emit.Opcode(buf.BinWriter, opcode.CHECKMULTISIG)
|
||||
emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
|
||||
emit.Syscall(buf.BinWriter, "Neo.Crypto.ECDsaCheckMultiSig")
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -24,11 +25,14 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
|
|||
assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB()))
|
||||
|
||||
for i := 0; i < len(validators); i++ {
|
||||
assert.EqualValues(t, opcode.PUSHDATA1, br.ReadB())
|
||||
bb := br.ReadVarBytes()
|
||||
require.NoError(t, br.Err)
|
||||
assert.Equal(t, validators[i].Bytes(), bb)
|
||||
}
|
||||
|
||||
assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB()))
|
||||
assert.Equal(t, opcode.CHECKMULTISIG, 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())
|
||||
}
|
||||
|
|
|
@ -3,9 +3,15 @@ package vm
|
|||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
)
|
||||
|
||||
var (
|
||||
verifyInteropID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
|
||||
multisigInteropID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
|
||||
)
|
||||
|
||||
func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) {
|
||||
var nthings int
|
||||
|
||||
|
@ -55,9 +61,12 @@ func ParseMultiSigContract(script []byte) ([][]byte, bool) {
|
|||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
if instr != opcode.PUSHBYTES33 {
|
||||
if instr != opcode.PUSHDATA1 {
|
||||
break
|
||||
}
|
||||
if len(param) < 33 {
|
||||
return nil, false
|
||||
}
|
||||
pubs = append(pubs, param)
|
||||
nkeys++
|
||||
if nkeys > MaxArraySize {
|
||||
|
@ -75,7 +84,11 @@ func ParseMultiSigContract(script []byte) ([][]byte, bool) {
|
|||
return nil, false
|
||||
}
|
||||
instr, _, err = ctx.Next()
|
||||
if err != nil || instr != opcode.CHECKMULTISIG {
|
||||
if err != nil || instr != opcode.PUSHNULL {
|
||||
return nil, false
|
||||
}
|
||||
instr, param, err = ctx.Next()
|
||||
if err != nil || instr != opcode.SYSCALL || binary.LittleEndian.Uint32(param) != multisigInteropID {
|
||||
return nil, false
|
||||
}
|
||||
instr, _, err = ctx.Next()
|
||||
|
@ -88,17 +101,21 @@ func ParseMultiSigContract(script []byte) ([][]byte, bool) {
|
|||
// IsSignatureContract checks whether the passed script is a signature check
|
||||
// contract.
|
||||
func IsSignatureContract(script []byte) bool {
|
||||
if len(script) != 41 {
|
||||
return false
|
||||
}
|
||||
|
||||
ctx := NewContext(script)
|
||||
instr, _, err := ctx.Next()
|
||||
if err != nil || instr != opcode.PUSHBYTES33 {
|
||||
instr, param, err := ctx.Next()
|
||||
if err != nil || instr != opcode.PUSHDATA1 || len(param) != 33 {
|
||||
return false
|
||||
}
|
||||
instr, _, err = ctx.Next()
|
||||
if err != nil || instr != opcode.CHECKSIG {
|
||||
if err != nil || instr != opcode.PUSHNULL {
|
||||
return false
|
||||
}
|
||||
instr, _, err = ctx.Next()
|
||||
if err != nil || instr != opcode.RET || ctx.ip != len(script) {
|
||||
instr, param, err = ctx.Next()
|
||||
if err != nil || instr != opcode.SYSCALL || binary.LittleEndian.Uint32(param) != verifyInteropID {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -1,228 +1,117 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIsSignatureContractGood(t *testing.T) {
|
||||
prog := make([]byte, 35)
|
||||
prog[0] = byte(opcode.PUSHBYTES33)
|
||||
prog[34] = byte(opcode.CHECKSIG)
|
||||
assert.Equal(t, true, IsSignatureContract(prog))
|
||||
assert.Equal(t, true, IsStandardContract(prog))
|
||||
func testSignatureContract() []byte {
|
||||
prog := make([]byte, 41)
|
||||
prog[0] = byte(opcode.PUSHDATA1)
|
||||
prog[1] = 33
|
||||
prog[35] = byte(opcode.PUSHNULL)
|
||||
prog[36] = byte(opcode.SYSCALL)
|
||||
binary.LittleEndian.PutUint32(prog[37:], verifyInteropID)
|
||||
return prog
|
||||
}
|
||||
|
||||
func TestIsSignatureContractBadNoCheckSig(t *testing.T) {
|
||||
prog := make([]byte, 34)
|
||||
prog[0] = byte(opcode.PUSHBYTES33)
|
||||
assert.Equal(t, false, IsSignatureContract(prog))
|
||||
assert.Equal(t, false, IsStandardContract(prog))
|
||||
func TestIsSignatureContract(t *testing.T) {
|
||||
t.Run("valid contract", func(t *testing.T) {
|
||||
prog := testSignatureContract()
|
||||
assert.True(t, IsSignatureContract(prog))
|
||||
assert.True(t, IsStandardContract(prog))
|
||||
})
|
||||
|
||||
t.Run("invalid interop ID", func(t *testing.T) {
|
||||
prog := testSignatureContract()
|
||||
binary.LittleEndian.PutUint32(prog[37:], ^verifyInteropID)
|
||||
assert.False(t, IsSignatureContract(prog))
|
||||
assert.False(t, IsStandardContract(prog))
|
||||
})
|
||||
|
||||
t.Run("invalid pubkey size", func(t *testing.T) {
|
||||
prog := testSignatureContract()
|
||||
prog[1] = 32
|
||||
assert.False(t, IsSignatureContract(prog))
|
||||
assert.False(t, IsStandardContract(prog))
|
||||
})
|
||||
|
||||
t.Run("no PUSHNULL", func(t *testing.T) {
|
||||
prog := testSignatureContract()
|
||||
prog[35] = byte(opcode.PUSH1)
|
||||
assert.False(t, IsSignatureContract(prog))
|
||||
assert.False(t, IsStandardContract(prog))
|
||||
})
|
||||
|
||||
t.Run("invalid length", func(t *testing.T) {
|
||||
prog := testSignatureContract()
|
||||
prog = append(prog, 0)
|
||||
assert.False(t, IsSignatureContract(prog))
|
||||
assert.False(t, IsStandardContract(prog))
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsSignatureContractBadNoCheckSig2(t *testing.T) {
|
||||
prog := make([]byte, 35)
|
||||
prog[0] = byte(opcode.PUSHBYTES33)
|
||||
prog[34] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsSignatureContract(prog))
|
||||
}
|
||||
|
||||
func TestIsSignatureContractBadWrongPush(t *testing.T) {
|
||||
prog := make([]byte, 35)
|
||||
prog[0] = byte(opcode.PUSHBYTES32)
|
||||
prog[33] = byte(opcode.NOP)
|
||||
prog[34] = byte(opcode.CHECKSIG)
|
||||
assert.Equal(t, false, IsSignatureContract(prog))
|
||||
}
|
||||
|
||||
func TestIsSignatureContractBadWrongInstr(t *testing.T) {
|
||||
prog := make([]byte, 30)
|
||||
prog[0] = byte(opcode.PUSHBYTES33)
|
||||
assert.Equal(t, false, IsSignatureContract(prog))
|
||||
}
|
||||
|
||||
func TestIsSignatureContractBadExcessiveInstr(t *testing.T) {
|
||||
prog := make([]byte, 36)
|
||||
prog[0] = byte(opcode.PUSHBYTES33)
|
||||
prog[34] = byte(opcode.CHECKSIG)
|
||||
prog[35] = byte(opcode.RET)
|
||||
assert.Equal(t, false, IsSignatureContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractGood(t *testing.T) {
|
||||
prog := make([]byte, 71)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, true, IsMultiSigContract(prog))
|
||||
assert.Equal(t, true, IsStandardContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractGoodPushBytes1(t *testing.T) {
|
||||
prog := make([]byte, 73)
|
||||
prog[0] = byte(opcode.PUSHBYTES1)
|
||||
prog[1] = 2
|
||||
prog[2] = byte(opcode.PUSHBYTES33)
|
||||
prog[36] = byte(opcode.PUSHBYTES33)
|
||||
prog[70] = byte(opcode.PUSHBYTES1)
|
||||
prog[71] = 2
|
||||
prog[72] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, true, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractGoodPushBytes2(t *testing.T) {
|
||||
prog := make([]byte, 75)
|
||||
prog[0] = byte(opcode.PUSHBYTES2)
|
||||
prog[1] = 2
|
||||
prog[3] = byte(opcode.PUSHBYTES33)
|
||||
prog[37] = byte(opcode.PUSHBYTES33)
|
||||
prog[71] = byte(opcode.PUSHBYTES2)
|
||||
prog[72] = 2
|
||||
prog[74] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, true, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadNSigs1(t *testing.T) {
|
||||
prog := make([]byte, 71)
|
||||
prog[0] = byte(opcode.PUSH0)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
assert.Equal(t, false, IsStandardContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadNSigs2(t *testing.T) {
|
||||
prog := make([]byte, 73)
|
||||
prog[0] = byte(opcode.PUSHBYTES2)
|
||||
prog[1] = 0xff
|
||||
prog[2] = 0xff
|
||||
prog[3] = byte(opcode.PUSHBYTES33)
|
||||
prog[37] = byte(opcode.PUSHBYTES33)
|
||||
prog[71] = byte(opcode.PUSH2)
|
||||
prog[72] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadNSigs3(t *testing.T) {
|
||||
prog := make([]byte, 71)
|
||||
prog[0] = byte(opcode.PUSH5)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadExcessiveNOP1(t *testing.T) {
|
||||
prog := make([]byte, 72)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.NOP)
|
||||
prog[2] = byte(opcode.PUSHBYTES33)
|
||||
prog[36] = byte(opcode.PUSHBYTES33)
|
||||
prog[70] = byte(opcode.PUSH2)
|
||||
prog[71] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadExcessiveNOP2(t *testing.T) {
|
||||
prog := make([]byte, 72)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.NOP)
|
||||
prog[36] = byte(opcode.PUSHBYTES33)
|
||||
prog[70] = byte(opcode.PUSH2)
|
||||
prog[71] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadExcessiveNOP3(t *testing.T) {
|
||||
prog := make([]byte, 72)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.NOP)
|
||||
prog[70] = byte(opcode.PUSH2)
|
||||
prog[71] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadExcessiveNOP4(t *testing.T) {
|
||||
prog := make([]byte, 72)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.NOP)
|
||||
prog[71] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadExcessiveNOP5(t *testing.T) {
|
||||
prog := make([]byte, 72)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.CHECKMULTISIG)
|
||||
prog[71] = byte(opcode.NOP)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadNKeys1(t *testing.T) {
|
||||
prog := make([]byte, 71)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH3)
|
||||
prog[70] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadNKeys2(t *testing.T) {
|
||||
prog := make([]byte, 1)
|
||||
prog[0] = byte(opcode.PUSH10)
|
||||
key := make([]byte, 33)
|
||||
var asize = uint16(MaxArraySize + 1)
|
||||
for i := 0; i < int(asize); i++ {
|
||||
prog = append(prog, byte(opcode.PUSHBYTES33))
|
||||
prog = append(prog, key...)
|
||||
func testMultisigContract(t *testing.T, n, m int) []byte {
|
||||
pubs := make(keys.PublicKeys, n)
|
||||
for i := 0; i < n; i++ {
|
||||
priv, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
pubs[i] = priv.PublicKey()
|
||||
}
|
||||
prog = append(prog, byte(opcode.PUSHBYTES2), byte(asize&0xff), byte((asize<<8)&0xff), byte(opcode.CHECKMULTISIG))
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
|
||||
prog, err := smartcontract.CreateMultiSigRedeemScript(m, pubs)
|
||||
require.NoError(t, err)
|
||||
return prog
|
||||
}
|
||||
|
||||
func TestIsMultiSigContractBadRead1(t *testing.T) {
|
||||
prog := make([]byte, 71)
|
||||
prog[0] = byte(opcode.PUSHBYTES75)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
func TestIsMultiSigContract(t *testing.T) {
|
||||
t.Run("valid contract", func(t *testing.T) {
|
||||
prog := testMultisigContract(t, 2, 2)
|
||||
assert.True(t, IsMultiSigContract(prog))
|
||||
assert.True(t, IsStandardContract(prog))
|
||||
})
|
||||
|
||||
func TestIsMultiSigContractBadRead2(t *testing.T) {
|
||||
prog := make([]byte, 71)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES75)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.CHECKMULTISIG)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
}
|
||||
t.Run("0-length", func(t *testing.T) {
|
||||
assert.False(t, IsMultiSigContract([]byte{}))
|
||||
})
|
||||
|
||||
func TestIsMultiSigContractBadRead3(t *testing.T) {
|
||||
prog := make([]byte, 71)
|
||||
prog[0] = byte(opcode.PUSH2)
|
||||
prog[1] = byte(opcode.PUSHBYTES33)
|
||||
prog[35] = byte(opcode.PUSHBYTES33)
|
||||
prog[69] = byte(opcode.PUSH2)
|
||||
prog[70] = byte(opcode.PUSHBYTES1)
|
||||
assert.Equal(t, false, IsMultiSigContract(prog))
|
||||
t.Run("invalid param", func(t *testing.T) {
|
||||
prog := []byte{byte(opcode.PUSHDATA1), 10}
|
||||
assert.False(t, IsMultiSigContract(prog))
|
||||
})
|
||||
|
||||
t.Run("too many keys", func(t *testing.T) {
|
||||
prog := testMultisigContract(t, 1025, 1)
|
||||
assert.False(t, IsMultiSigContract(prog))
|
||||
})
|
||||
|
||||
t.Run("invalid interop ID", func(t *testing.T) {
|
||||
prog := testMultisigContract(t, 2, 2)
|
||||
prog[len(prog)-4] ^= 0xFF
|
||||
assert.False(t, IsMultiSigContract(prog))
|
||||
})
|
||||
|
||||
t.Run("no PUSHNULL", func(t *testing.T) {
|
||||
prog := testMultisigContract(t, 2, 2)
|
||||
prog[len(prog)-6] ^= 0xFF
|
||||
assert.False(t, IsMultiSigContract(prog))
|
||||
})
|
||||
|
||||
t.Run("invalid keys number", func(t *testing.T) {
|
||||
prog := testMultisigContract(t, 2, 2)
|
||||
prog[len(prog)-7] = byte(opcode.PUSH3)
|
||||
assert.False(t, IsMultiSigContract(prog))
|
||||
})
|
||||
|
||||
t.Run("invalid length", func(t *testing.T) {
|
||||
prog := testMultisigContract(t, 2, 2)
|
||||
prog = append(prog, 0)
|
||||
assert.False(t, IsMultiSigContract(prog))
|
||||
})
|
||||
}
|
||||
|
|
49
pkg/vm/vm.go
49
pkg/vm/vm.go
|
@ -1196,45 +1196,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
v.astack = v.Context().astack
|
||||
}
|
||||
|
||||
case opcode.CHECKSIG, opcode.VERIFY:
|
||||
var hashToCheck []byte
|
||||
|
||||
keyb := v.estack.Pop().Bytes()
|
||||
signature := v.estack.Pop().Bytes()
|
||||
if op == opcode.CHECKSIG {
|
||||
if v.checkhash == nil {
|
||||
panic("VM is not set up properly for signature checks")
|
||||
}
|
||||
hashToCheck = v.checkhash
|
||||
} else { // VERIFY
|
||||
msg := v.estack.Pop().Bytes()
|
||||
hashToCheck = hash.Sha256(msg).BytesBE()
|
||||
}
|
||||
pkey := v.bytesToPublicKey(keyb)
|
||||
res := pkey.Verify(signature, hashToCheck)
|
||||
v.estack.PushVal(res)
|
||||
|
||||
case opcode.CHECKMULTISIG:
|
||||
pkeys, err := v.estack.PopSigElements()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("wrong parameters: %s", err.Error()))
|
||||
}
|
||||
sigs, err := v.estack.PopSigElements()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("wrong parameters: %s", err.Error()))
|
||||
}
|
||||
// It's ok to have more keys than there are signatures (it would
|
||||
// just mean that some keys didn't sign), but not the other way around.
|
||||
if len(pkeys) < len(sigs) {
|
||||
panic("more signatures than there are keys")
|
||||
}
|
||||
if v.checkhash == nil {
|
||||
panic("VM is not set up properly for signature checks")
|
||||
}
|
||||
|
||||
sigok := CheckMultisigPar(v, pkeys, sigs)
|
||||
v.estack.PushVal(sigok)
|
||||
|
||||
case opcode.NEWMAP:
|
||||
v.estack.Push(&Element{value: NewMapItem()})
|
||||
|
||||
|
@ -1419,9 +1380,9 @@ func (v *VM) getJumpOffset(ctx *Context, parameter []byte, mod int) int {
|
|||
}
|
||||
|
||||
// CheckMultisigPar checks if sigs contains sufficient valid signatures.
|
||||
func CheckMultisigPar(v *VM, pkeys [][]byte, sigs [][]byte) bool {
|
||||
func CheckMultisigPar(v *VM, h []byte, pkeys [][]byte, sigs [][]byte) bool {
|
||||
if len(sigs) == 1 {
|
||||
return checkMultisig1(v, pkeys, sigs[0])
|
||||
return checkMultisig1(v, h, pkeys, sigs[0])
|
||||
}
|
||||
|
||||
k1, k2 := 0, len(pkeys)-1
|
||||
|
@ -1446,7 +1407,7 @@ func CheckMultisigPar(v *VM, pkeys [][]byte, sigs [][]byte) bool {
|
|||
|
||||
result <- verify{
|
||||
signum: t.signum,
|
||||
ok: t.pub.Verify(sigs[t.signum], v.checkhash),
|
||||
ok: t.pub.Verify(sigs[t.signum], h),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1511,10 +1472,10 @@ loop:
|
|||
return sigok
|
||||
}
|
||||
|
||||
func checkMultisig1(v *VM, pkeys [][]byte, sig []byte) bool {
|
||||
func checkMultisig1(v *VM, h []byte, pkeys [][]byte, sig []byte) bool {
|
||||
for i := range pkeys {
|
||||
pkey := v.bytesToPublicKey(pkeys[i])
|
||||
if pkey.Verify(sig, v.checkhash) {
|
||||
if pkey.Verify(sig, h) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ import (
|
|||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
|
@ -2603,292 +2601,6 @@ func TestREMOVEMap(t *testing.T) {
|
|||
assert.Equal(t, makeStackItem(false), vm.estack.Pop().value)
|
||||
}
|
||||
|
||||
func TestCHECKSIGNoArgs(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKSIG)
|
||||
vm := load(prog)
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKSIGOneArg(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKSIG)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
pbytes := pk.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.estack.PushVal(pbytes)
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKSIGNoSigLoaded(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKSIG)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := "NEO - An Open Network For Smart Economy"
|
||||
sig := pk.Sign([]byte(msg))
|
||||
pbytes := pk.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.estack.PushVal(sig)
|
||||
vm.estack.PushVal(pbytes)
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKSIGBadKey(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKSIG)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig := pk.Sign(msg)
|
||||
pbytes := pk.PublicKey().Bytes()[:4]
|
||||
vm := load(prog)
|
||||
vm.SetCheckedHash(hash.Sha256(msg).BytesBE())
|
||||
vm.estack.PushVal(sig)
|
||||
vm.estack.PushVal(pbytes)
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKSIGWrongSig(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKSIG)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig := pk.Sign(msg)
|
||||
pbytes := pk.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.SetCheckedHash(hash.Sha256(msg).BytesBE())
|
||||
vm.estack.PushVal(util.ArrayReverse(sig))
|
||||
vm.estack.PushVal(pbytes)
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, false, vm.estack.Pop().Bool())
|
||||
}
|
||||
|
||||
func TestCHECKSIGGood(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKSIG)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig := pk.Sign(msg)
|
||||
pbytes := pk.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.SetCheckedHash(hash.Sha256(msg).BytesBE())
|
||||
vm.estack.PushVal(sig)
|
||||
vm.estack.PushVal(pbytes)
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, true, vm.estack.Pop().Bool())
|
||||
}
|
||||
|
||||
func TestVERIFYGood(t *testing.T) {
|
||||
prog := makeProgram(opcode.VERIFY)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig := pk.Sign(msg)
|
||||
pbytes := pk.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.estack.PushVal(msg)
|
||||
vm.estack.PushVal(sig)
|
||||
vm.estack.PushVal(pbytes)
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, true, vm.estack.Pop().Bool())
|
||||
}
|
||||
|
||||
func TestVERIFYBad(t *testing.T) {
|
||||
prog := makeProgram(opcode.VERIFY)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig := pk.Sign(msg)
|
||||
pbytes := pk.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.estack.PushVal(util.ArrayReverse(msg))
|
||||
vm.estack.PushVal(sig)
|
||||
vm.estack.PushVal(pbytes)
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, false, vm.estack.Pop().Bool())
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGNoArgs(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
vm := load(prog)
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGOneArg(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
pk, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
vm := load(prog)
|
||||
pbytes := pk.PublicKey().Bytes()
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes)})
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGNotEnoughKeys(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
pk1, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
pk2, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig1 := pk1.Sign(msg)
|
||||
sig2 := pk2.Sign(msg)
|
||||
pbytes1 := pk1.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.SetCheckedHash(hash.Sha256(msg).BytesBE())
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(sig1), NewByteArrayItem(sig2)})
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1)})
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGNoHash(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
pk1, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
pk2, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig1 := pk1.Sign(msg)
|
||||
sig2 := pk2.Sign(msg)
|
||||
pbytes1 := pk1.PublicKey().Bytes()
|
||||
pbytes2 := pk2.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(sig1), NewByteArrayItem(sig2)})
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1), NewByteArrayItem(pbytes2)})
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGBadKey(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
pk1, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
pk2, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig1 := pk1.Sign(msg)
|
||||
sig2 := pk2.Sign(msg)
|
||||
pbytes1 := pk1.PublicKey().Bytes()
|
||||
pbytes2 := pk2.PublicKey().Bytes()[:4]
|
||||
vm := load(prog)
|
||||
vm.SetCheckedHash(hash.Sha256(msg).BytesBE())
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(sig1), NewByteArrayItem(sig2)})
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1), NewByteArrayItem(pbytes2)})
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGBadSig(t *testing.T) {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
pk1, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
pk2, err := keys.NewPrivateKey()
|
||||
assert.Nil(t, err)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
sig1 := pk1.Sign(msg)
|
||||
sig2 := pk2.Sign(msg)
|
||||
pbytes1 := pk1.PublicKey().Bytes()
|
||||
pbytes2 := pk2.PublicKey().Bytes()
|
||||
vm := load(prog)
|
||||
vm.SetCheckedHash(hash.Sha256(msg).BytesBE())
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(util.ArrayReverse(sig1)), NewByteArrayItem(sig2)})
|
||||
vm.estack.PushVal([]StackItem{NewByteArrayItem(pbytes1), NewByteArrayItem(pbytes2)})
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, false, vm.estack.Pop().Bool())
|
||||
}
|
||||
|
||||
func initCHECKMULTISIG(msg []byte, n int) ([]StackItem, []StackItem, map[string]*keys.PublicKey, error) {
|
||||
var err error
|
||||
|
||||
keyMap := make(map[string]*keys.PublicKey)
|
||||
pkeys := make([]*keys.PrivateKey, n)
|
||||
pubs := make([]StackItem, n)
|
||||
for i := range pubs {
|
||||
pkeys[i], err = keys.NewPrivateKey()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
pk := pkeys[i].PublicKey()
|
||||
data := pk.Bytes()
|
||||
pubs[i] = NewByteArrayItem(data)
|
||||
keyMap[string(data)] = pk
|
||||
}
|
||||
|
||||
sigs := make([]StackItem, n)
|
||||
for i := range sigs {
|
||||
sig := pkeys[i].Sign(msg)
|
||||
sigs[i] = NewByteArrayItem(sig)
|
||||
}
|
||||
|
||||
return pubs, sigs, keyMap, nil
|
||||
}
|
||||
|
||||
func subSlice(arr []StackItem, indices []int) []StackItem {
|
||||
if indices == nil {
|
||||
return arr
|
||||
}
|
||||
|
||||
result := make([]StackItem, len(indices))
|
||||
for i, j := range indices {
|
||||
result[i] = arr[j]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func initCHECKMULTISIGVM(t *testing.T, n int, ik, is []int) *VM {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
v := load(prog)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
|
||||
v.SetCheckedHash(hash.Sha256(msg).BytesBE())
|
||||
|
||||
pubs, sigs, _, err := initCHECKMULTISIG(msg, n)
|
||||
require.NoError(t, err)
|
||||
|
||||
pubs = subSlice(pubs, ik)
|
||||
sigs = subSlice(sigs, is)
|
||||
|
||||
v.estack.PushVal(sigs)
|
||||
v.estack.PushVal(pubs)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func testCHECKMULTISIGGood(t *testing.T, n int, is []int) {
|
||||
v := initCHECKMULTISIGVM(t, n, nil, is)
|
||||
|
||||
runVM(t, v)
|
||||
assert.Equal(t, 1, v.estack.Len())
|
||||
assert.True(t, v.estack.Pop().Bool())
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGGood(t *testing.T) {
|
||||
t.Run("3_1", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{1}) })
|
||||
t.Run("2_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 2, []int{0, 1}) })
|
||||
t.Run("3_3", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{0, 1, 2}) })
|
||||
t.Run("3_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{0, 2}) })
|
||||
t.Run("4_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 4, []int{0, 2}) })
|
||||
t.Run("10_7", func(t *testing.T) { testCHECKMULTISIGGood(t, 10, []int{2, 3, 4, 5, 6, 8, 9}) })
|
||||
t.Run("12_9", func(t *testing.T) { testCHECKMULTISIGGood(t, 12, []int{0, 1, 4, 5, 6, 7, 8, 9}) })
|
||||
}
|
||||
|
||||
func testCHECKMULTISIGBad(t *testing.T, n int, ik, is []int) {
|
||||
v := initCHECKMULTISIGVM(t, n, ik, is)
|
||||
|
||||
runVM(t, v)
|
||||
assert.Equal(t, 1, v.estack.Len())
|
||||
assert.False(t, v.estack.Pop().Bool())
|
||||
}
|
||||
|
||||
func TestCHECKMULTISIGBad(t *testing.T) {
|
||||
t.Run("1_1 wrong signature", func(t *testing.T) { testCHECKMULTISIGBad(t, 2, []int{0}, []int{1}) })
|
||||
t.Run("3_2 wrong order", func(t *testing.T) { testCHECKMULTISIGBad(t, 3, []int{0, 2}, []int{2, 0}) })
|
||||
t.Run("3_2 duplicate sig", func(t *testing.T) { testCHECKMULTISIGBad(t, 3, nil, []int{0, 0}) })
|
||||
}
|
||||
|
||||
func TestSWAPGood(t *testing.T) {
|
||||
prog := makeProgram(opcode.SWAP)
|
||||
vm := load(prog)
|
||||
|
|
|
@ -90,7 +90,7 @@ func TestContract_ScriptHash(t *testing.T) {
|
|||
|
||||
func TestAccount_ConvertMultisig(t *testing.T) {
|
||||
// test is based on a wallet1_solo.json accounts from neo-local
|
||||
a, err := NewAccountFromEncryptedWIF("6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y", "one")
|
||||
a, err := NewAccountFromEncryptedWIF("6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN", "one")
|
||||
require.NoError(t, err)
|
||||
|
||||
hexs := []string{
|
||||
|
@ -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, "AbU69m8WUZJSWanfr1Cy66cpEcsmMcX7BR", a.Address)
|
||||
require.Equal(t, "Ab3TJfgpa94yDr1WPeXpYQiChTRohBJ6T5", 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, "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU", a.Address)
|
||||
require.Equal(t, "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6", a.Address)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
57
pkg/wallet/testdata/wallet1.json
vendored
57
pkg/wallet/testdata/wallet1.json
vendored
|
@ -1 +1,56 @@
|
|||
{"name":"wallet1","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet1",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "4c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc250680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
75
pkg/wallet/testdata/wallet2.json
vendored
75
pkg/wallet/testdata/wallet2.json
vendored
|
@ -1 +1,74 @@
|
|||
{"name":"wallet2","version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs","label":null,"isDefault":false,"lock":false,"key":"6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y","contract":{"script":"2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2ac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null},{"address":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","label":null,"isDefault":false,"lock":false,"key":"6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L","contract":{"script":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae","parameters":[{"name":"parameter0","type":"Signature"},{"name":"parameter1","type":"Signature"},{"name":"parameter2","type":"Signature"}],"deployed":false},"extra":null},{"address":"AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17","label":null,"isDefault":true,"lock":false,"key":"6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L","contract":{"script":"2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406eac","parameters":[{"name":"parameter0","type":"Signature"}],"deployed":false},"extra":null}],"extra":null}
|
||||
{
|
||||
"name": "wallet2",
|
||||
"version": "1.0",
|
||||
"scrypt": {
|
||||
"n": 16384,
|
||||
"r": 8,
|
||||
"p": 8
|
||||
},
|
||||
"accounts": [
|
||||
{
|
||||
"address": "AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "4c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc250680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AbHd9dXYUryuCvMgXRUfdR6zC2CJixS6Q6",
|
||||
"label": null,
|
||||
"isDefault": false,
|
||||
"lock": false,
|
||||
"key": "6PYKYQKRs758NBX4q5k6fSmduZDfEfQyoXMovQU5myKm2h5ArXuYpuMEaN",
|
||||
"contract": {
|
||||
"script": "534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter1",
|
||||
"type": "Signature"
|
||||
},
|
||||
{
|
||||
"name": "parameter2",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
},
|
||||
{
|
||||
"address": "AdB6ayKfBRJZasiXX4JL5N2YtmxftNp1b3",
|
||||
"label": null,
|
||||
"isDefault": true,
|
||||
"lock": false,
|
||||
"key": "6PYXPEFeBxeDjqMiwRrSe81LnpL1cpw1WSwENJY1p4NtgSbfZPaUFy8Kkg",
|
||||
"contract": {
|
||||
"script": "4c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e50680a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
"type": "Signature"
|
||||
}
|
||||
],
|
||||
"deployed": false
|
||||
},
|
||||
"extra": null
|
||||
}
|
||||
],
|
||||
"extra": null
|
||||
}
|
||||
|
|
|
@ -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("AKkkumHbBipZ46UMZJoFynJMXzSRnBvKcs")
|
||||
expected, err := address.StringToUint160("AQyx83BYr1PkyYhZhUAogaHdhkLVHn6htY")
|
||||
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("AWLYWXB8C9Lt1nHdDZJnC5cpYJjgRDLk17")
|
||||
expected, err = address.StringToUint160("AdB6ayKfBRJZasiXX4JL5N2YtmxftNp1b3")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, sh)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue