forked from TrueCloudLab/neoneo-go
Merge pull request #603 from nspcc-dev/feature/wallet
consensus: use wallets instead of WIF, closes #588.
This commit is contained in:
commit
f4aa088d04
23 changed files with 186 additions and 38 deletions
|
@ -19,6 +19,7 @@ services:
|
|||
command: "node --config-path /config --privnet"
|
||||
volumes:
|
||||
- ../config/protocol.privnet.docker.one.yml:/config/protocol.privnet.yml
|
||||
- ./wallets/wallet1.json:/wallet1.json
|
||||
- volume_chain:/chains
|
||||
networks:
|
||||
neo_go_network:
|
||||
|
@ -33,6 +34,7 @@ services:
|
|||
command: "node --config-path /config --privnet"
|
||||
volumes:
|
||||
- ../config/protocol.privnet.docker.two.yml:/config/protocol.privnet.yml
|
||||
- ./wallets/wallet2.json:/wallet2.json
|
||||
- volume_chain:/chains
|
||||
networks:
|
||||
neo_go_network:
|
||||
|
@ -47,6 +49,7 @@ services:
|
|||
command: "node --config-path /config --privnet"
|
||||
volumes:
|
||||
- ../config/protocol.privnet.docker.three.yml:/config/protocol.privnet.yml
|
||||
- ./wallets/wallet3.json:/wallet3.json
|
||||
- volume_chain:/chains
|
||||
networks:
|
||||
neo_go_network:
|
||||
|
@ -61,6 +64,7 @@ services:
|
|||
command: "node --config-path /config --privnet"
|
||||
volumes:
|
||||
- ../config/protocol.privnet.docker.four.yml:/config/protocol.privnet.yml
|
||||
- ./wallets/wallet4.json:/wallet4.json
|
||||
- volume_chain:/chains
|
||||
networks:
|
||||
neo_go_network:
|
||||
|
@ -75,6 +79,7 @@ services:
|
|||
command: "node --config-path /config --privnet"
|
||||
volumes:
|
||||
- ../config/protocol.privnet.docker.single.yml:/config/protocol.privnet.yml
|
||||
- ./wallets/wallet1.json:/wallet1.json
|
||||
- volume_chain:/chains
|
||||
- ./1600-privnet-blocks-single.acc.gz:/privnet-blocks.acc.gz
|
||||
networks:
|
||||
|
|
1
.docker/wallets/wallet1.json
Normal file
1
.docker/wallets/wallet1.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
1
.docker/wallets/wallet1_solo.json
Normal file
1
.docker/wallets/wallet1_solo.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
1
.docker/wallets/wallet2.json
Normal file
1
.docker/wallets/wallet2.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
1
.docker/wallets/wallet3.json
Normal file
1
.docker/wallets/wallet3.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
1
.docker/wallets/wallet4.json
Normal file
1
.docker/wallets/wallet4.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
|
@ -57,5 +57,5 @@ ApplicationConfiguration:
|
|||
Enabled: false
|
||||
Port: 20014
|
||||
UnlockWallet:
|
||||
Path: "6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc"
|
||||
Path: "/wallet4.json"
|
||||
Password: "four"
|
||||
|
|
|
@ -57,5 +57,5 @@ ApplicationConfiguration:
|
|||
Enabled: false
|
||||
Port: 20011
|
||||
UnlockWallet:
|
||||
Path: "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y"
|
||||
Path: "/wallet1.json"
|
||||
Password: "one"
|
||||
|
|
|
@ -51,5 +51,5 @@ ApplicationConfiguration:
|
|||
Enabled: false
|
||||
Port: 20011
|
||||
UnlockWallet:
|
||||
Path: "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y"
|
||||
Path: "/wallet1.json"
|
||||
Password: "one"
|
||||
|
|
|
@ -57,5 +57,5 @@ ApplicationConfiguration:
|
|||
Enabled: false
|
||||
Port: 20013
|
||||
UnlockWallet:
|
||||
Path: "6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh"
|
||||
Path: "/wallet3.json"
|
||||
Password: "three"
|
||||
|
|
|
@ -57,5 +57,5 @@ ApplicationConfiguration:
|
|||
Enabled: false
|
||||
Port: 20012
|
||||
UnlockWallet:
|
||||
Path: "6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L"
|
||||
Path: "/wallet2.json"
|
||||
Password: "two"
|
||||
|
|
2
go.mod
2
go.mod
|
@ -7,7 +7,7 @@ require (
|
|||
github.com/go-redis/redis v6.10.2+incompatible
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||
github.com/mr-tron/base58 v1.1.2
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200116150450-80b3f6f0dff8
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a
|
||||
github.com/nspcc-dev/rfc6979 v0.2.0
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/prometheus/client_golang v1.2.1
|
||||
|
|
4
go.sum
4
go.sum
|
@ -94,8 +94,8 @@ github.com/nspcc-dev/dbft v0.0.0-20191205084618-dacb1a30c254 h1:A4OkQDQOSPsJF8qU
|
|||
github.com/nspcc-dev/dbft v0.0.0-20191205084618-dacb1a30c254/go.mod h1:w1Ln2aT+dBlPhLnuZhBV+DfPEdS2CHWWLp5JTScY3bw=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20191209120240-0d6b7568d9ae h1:T5V1QANlNMKun0EPB3eqg2PTXG4rmLhzDyEiV63kdB0=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20191209120240-0d6b7568d9ae/go.mod h1:3FjXOoHmA51EGfb5GS/HOv7VdmngNRTssSeQ729dvGY=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200116150450-80b3f6f0dff8 h1:WjfnKH75ncU5iySB6ooTsbg2P0q1iQoecTN4gHIuEbs=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200116150450-80b3f6f0dff8/go.mod h1:/YFK+XOxxg0Bfm6P92lY5eDSLYfp06XOdL8KAVgXjVk=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a h1:ajvxgEe9qY4vvoSmrADqdDx7hReodKTnT2IXN++qZG8=
|
||||
github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a/go.mod h1:/YFK+XOxxg0Bfm6P92lY5eDSLYfp06XOdL8KAVgXjVk=
|
||||
github.com/nspcc-dev/neofs-crypto v0.2.0 h1:ftN+59WqxSWz/RCgXYOfhmltOOqU+udsNQSvN6wkFck=
|
||||
github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=
|
||||
github.com/nspcc-dev/neofs-crypto v0.2.3 h1:aca3X2aly92ENRbFK+kH6Hd+J9EQ4Eu6XMVoITSIKtc=
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
|
||||
"github.com/CityOfZion/neo-go/pkg/wallet"
|
||||
"github.com/nspcc-dev/dbft"
|
||||
"github.com/nspcc-dev/dbft/block"
|
||||
"github.com/nspcc-dev/dbft/crypto"
|
||||
|
@ -56,6 +57,7 @@ type service struct {
|
|||
messages chan Payload
|
||||
transactions chan *transaction.Transaction
|
||||
lastProposal []util.Uint256
|
||||
wallet *wallet.Wallet
|
||||
}
|
||||
|
||||
// Config is a configuration for consensus services.
|
||||
|
@ -104,12 +106,18 @@ func NewService(cfg Config) (Service, error) {
|
|||
return srv, nil
|
||||
}
|
||||
|
||||
priv, pub := getKeyPair(cfg.Wallet)
|
||||
var err error
|
||||
|
||||
if srv.wallet, err = wallet.NewWalletFromFile(cfg.Wallet.Path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer srv.wallet.Close()
|
||||
|
||||
srv.dbft = dbft.New(
|
||||
dbft.WithLogger(srv.log),
|
||||
dbft.WithSecondsPerBlock(cfg.TimePerBlock),
|
||||
dbft.WithKeyPair(priv, pub),
|
||||
dbft.WithGetKeyPair(srv.getKeyPair),
|
||||
dbft.WithTxPerBlock(10000),
|
||||
dbft.WithRequestTx(cfg.RequestTx),
|
||||
dbft.WithGetTx(srv.getTx),
|
||||
|
@ -180,14 +188,23 @@ func (s *service) validatePayload(p *Payload) bool {
|
|||
return p.Verify(h)
|
||||
}
|
||||
|
||||
func getKeyPair(cfg *config.WalletConfig) (crypto.PrivateKey, crypto.PublicKey) {
|
||||
// TODO: replace with wallet opening from the given path (#588)
|
||||
key, err := keys.NEP2Decrypt(cfg.Path, cfg.Password)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
func (s *service) getKeyPair(pubs []crypto.PublicKey) (int, crypto.PrivateKey, crypto.PublicKey) {
|
||||
for i := range pubs {
|
||||
script := pubs[i].(*publicKey).GetVerificationScript()
|
||||
acc := s.wallet.GetAccount(hash.Hash160(script))
|
||||
if acc == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
key, err := keys.NEP2Decrypt(acc.EncryptedWIF, s.Config.Wallet.Password)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
return i, &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
||||
}
|
||||
|
||||
return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
||||
return -1, nil, nil
|
||||
}
|
||||
|
||||
// OnPayload handles Payload receive.
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/dbft/block"
|
||||
"github.com/nspcc-dev/dbft/payload"
|
||||
|
@ -182,7 +183,7 @@ func newTestService(t *testing.T) *service {
|
|||
Chain: newTestChain(t),
|
||||
RequestTx: func(...util.Uint256) {},
|
||||
Wallet: &config.WalletConfig{
|
||||
Path: "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y",
|
||||
Path: "./testdata/wallet1.json",
|
||||
Password: "one",
|
||||
},
|
||||
})
|
||||
|
@ -192,35 +193,35 @@ func newTestService(t *testing.T) *service {
|
|||
}
|
||||
|
||||
func getTestValidator(i int) (*privateKey, *publicKey) {
|
||||
var wallet *config.WalletConfig
|
||||
var wif, password string
|
||||
|
||||
switch i {
|
||||
case 0:
|
||||
wallet = &config.WalletConfig{
|
||||
Path: "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y",
|
||||
Password: "one",
|
||||
}
|
||||
wif = "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y"
|
||||
password = "one"
|
||||
|
||||
case 1:
|
||||
wallet = &config.WalletConfig{
|
||||
Path: "6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L",
|
||||
Password: "two",
|
||||
}
|
||||
wif = "6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L"
|
||||
password = "two"
|
||||
|
||||
case 2:
|
||||
wallet = &config.WalletConfig{
|
||||
Path: "6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh",
|
||||
Password: "three",
|
||||
}
|
||||
wif = "6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh"
|
||||
password = "three"
|
||||
|
||||
case 3:
|
||||
wallet = &config.WalletConfig{
|
||||
Path: "6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc",
|
||||
Password: "four",
|
||||
}
|
||||
wif = "6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc"
|
||||
password = "four"
|
||||
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
priv, pub := getKeyPair(wallet)
|
||||
key, err := keys.NEP2Decrypt(wif, password)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return priv.(*privateKey), pub.(*publicKey)
|
||||
return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
||||
}
|
||||
|
||||
func newTestChain(t *testing.T) *core.Blockchain {
|
||||
|
|
1
pkg/consensus/testdata/wallet1.json
vendored
Normal file
1
pkg/consensus/testdata/wallet1.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
1
pkg/consensus/testdata/wallet2.json
vendored
Normal file
1
pkg/consensus/testdata/wallet2.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
1
pkg/consensus/testdata/wallet3.json
vendored
Normal file
1
pkg/consensus/testdata/wallet3.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
1
pkg/consensus/testdata/wallet4.json
vendored
Normal file
1
pkg/consensus/testdata/wallet4.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"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}
|
|
@ -1,8 +1,11 @@
|
|||
package wallet
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -43,8 +46,8 @@ type Account struct {
|
|||
// Contract represents a subset of the smartcontract to embed in the
|
||||
// Account so it's NEP-6 compliant.
|
||||
type Contract struct {
|
||||
// Script hash of the contract deployed on the blockchain.
|
||||
Script util.Uint160 `json:"script"`
|
||||
// Script of the contract deployed on the blockchain.
|
||||
Script []byte `json:"script"`
|
||||
|
||||
// A list of parameters used deploying this contract.
|
||||
Parameters []interface{} `json:"parameters"`
|
||||
|
@ -53,6 +56,54 @@ type Contract struct {
|
|||
Deployed bool `json:"deployed"`
|
||||
}
|
||||
|
||||
// contract is an intermediate struct used for json unmarshalling.
|
||||
type contract struct {
|
||||
// Script is a hex-encoded script of the contract.
|
||||
Script string `json:"script"`
|
||||
|
||||
// A list of parameters used deploying this contract.
|
||||
Parameters []interface{} `json:"parameters"`
|
||||
|
||||
// Indicates whether the contract has been deployed to the blockchain.
|
||||
Deployed bool `json:"deployed"`
|
||||
}
|
||||
|
||||
// ScriptHash returns the hash of contract's script.
|
||||
func (c Contract) ScriptHash() util.Uint160 {
|
||||
return hash.Hash160(c.Script)
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (c Contract) MarshalJSON() ([]byte, error) {
|
||||
var cc contract
|
||||
|
||||
cc.Script = hex.EncodeToString(c.Script)
|
||||
cc.Parameters = c.Parameters
|
||||
cc.Deployed = c.Deployed
|
||||
|
||||
return json.Marshal(cc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface.
|
||||
func (c *Contract) UnmarshalJSON(data []byte) error {
|
||||
var cc contract
|
||||
|
||||
if err := json.Unmarshal(data, &cc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
script, err := hex.DecodeString(cc.Script)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Script = script
|
||||
c.Parameters = cc.Parameters
|
||||
c.Deployed = cc.Deployed
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewAccount creates a new Account with a random generated PrivateKey.
|
||||
func NewAccount() (*Account, error) {
|
||||
priv, err := keys.NewPrivateKey()
|
||||
|
|
|
@ -2,8 +2,10 @@ package wallet
|
|||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||
"github.com/CityOfZion/neo-go/pkg/internal/keytestcases"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -47,6 +49,31 @@ func TestNewFromWif(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContract_MarshalJSON(t *testing.T) {
|
||||
var c Contract
|
||||
|
||||
data := []byte(`{"script":"0102","parameters":[1],"deployed":false}`)
|
||||
require.NoError(t, json.Unmarshal(data, &c))
|
||||
require.Equal(t, []byte{1, 2}, c.Script)
|
||||
|
||||
result, err := json.Marshal(c)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, string(data), string(result))
|
||||
|
||||
data = []byte(`1`)
|
||||
require.Error(t, json.Unmarshal(data, &c))
|
||||
|
||||
data = []byte(`{"script":"ERROR","parameters":[1],"deployed":false}`)
|
||||
require.Error(t, json.Unmarshal(data, &c))
|
||||
}
|
||||
|
||||
func TestContract_ScriptHash(t *testing.T) {
|
||||
script := []byte{0, 1, 2, 3}
|
||||
c := &Contract{Script: script}
|
||||
|
||||
require.Equal(t, hash.Hash160(script), c.ScriptHash())
|
||||
}
|
||||
|
||||
func compareFields(t *testing.T, tk keytestcases.Ktype, acc *Account) {
|
||||
if want, have := tk.Address, acc.Address; want != have {
|
||||
t.Fatalf("expected %s got %s", want, have)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -117,3 +118,14 @@ func (w *Wallet) Close() {
|
|||
rc.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// GetAccount returns account corresponding to the provided scripthash.
|
||||
func (w *Wallet) GetAccount(h util.Uint160) *Account {
|
||||
for _, acc := range w.Accounts {
|
||||
if c := acc.Contract; c != nil && h.Equals(c.ScriptHash()) {
|
||||
return acc
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -119,3 +120,28 @@ func removeWallet(t *testing.T, walletPath string) {
|
|||
err := os.RemoveAll(walletPath)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestWallet_GetAccount(t *testing.T) {
|
||||
wallet := checkWalletConstructor(t)
|
||||
accounts := []*Account{
|
||||
{
|
||||
Contract: &Contract{
|
||||
Script: []byte{0, 1, 2, 3},
|
||||
},
|
||||
},
|
||||
{
|
||||
Contract: &Contract{
|
||||
Script: []byte{3, 2, 1, 0},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, acc := range accounts {
|
||||
wallet.AddAccount(acc)
|
||||
}
|
||||
|
||||
for i, acc := range accounts {
|
||||
h := acc.Contract.ScriptHash()
|
||||
assert.Equal(t, acc, wallet.GetAccount(h), "can't get %d account", i)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue