2022-10-05 06:44:10 +00:00
package wallet_test
2020-08-31 13:17:44 +00:00
import (
2020-09-02 10:17:13 +00:00
"encoding/json"
2020-09-02 08:43:25 +00:00
"math/big"
2022-06-23 13:50:21 +00:00
"os"
2021-11-17 11:14:22 +00:00
"path/filepath"
2020-09-01 11:55:10 +00:00
"strings"
2020-08-31 13:17:44 +00:00
"testing"
2022-02-15 12:55:25 +00:00
"github.com/chzyer/readline"
2022-10-05 06:44:10 +00:00
"github.com/nspcc-dev/neo-go/internal/testcli"
2022-06-23 13:50:21 +00:00
"github.com/nspcc-dev/neo-go/pkg/config"
2020-09-01 12:05:07 +00:00
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
2020-08-31 13:17:44 +00:00
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
2020-09-02 09:20:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
2020-09-01 12:05:07 +00:00
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
2022-01-31 13:26:23 +00:00
"github.com/nspcc-dev/neo-go/pkg/util"
2020-08-31 13:17:44 +00:00
"github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/stretchr/testify/require"
2022-06-23 13:50:21 +00:00
"gopkg.in/yaml.v3"
2020-08-31 13:17:44 +00:00
)
2021-07-29 11:46:07 +00:00
func TestWalletAccountRemove ( t * testing . T ) {
2021-08-25 19:17:37 +00:00
tmpDir := t . TempDir ( )
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , false )
2021-07-29 11:46:07 +00:00
2021-11-17 11:14:22 +00:00
walletPath := filepath . Join ( tmpDir , "wallet.json" )
2021-07-29 11:46:07 +00:00
e . In . WriteString ( "acc1\r" )
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass\r" )
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath , "--account" )
e . In . WriteString ( "acc2\r" )
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass\r" )
e . Run ( t , "neo-go" , "wallet" , "create" , "--wallet" , walletPath )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet" , func ( t * testing . T ) {
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "address" not set ` , "neo-go" , "wallet" , "remove" )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "missing address" , func ( t * testing . T ) {
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "address" not set ` , "neo-go" , "wallet" , "remove" , "--wallet" , walletPath )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "invalid address" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "remove" , "--wallet" , walletPath ,
"--address" , util . Uint160 { } . StringLE ( ) )
} )
2021-07-29 11:46:07 +00:00
addr := w . Accounts [ 0 ] . Address
2022-01-31 13:26:23 +00:00
t . Run ( "askForConsent > no" , func ( t * testing . T ) {
e . In . WriteString ( "no" )
e . Run ( t , "neo-go" , "wallet" , "remove" , "--wallet" , walletPath ,
"--address" , addr )
actual , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Equal ( t , w , actual )
} )
2021-07-29 11:46:07 +00:00
e . Run ( t , "neo-go" , "wallet" , "remove" , "--wallet" , walletPath ,
"--address" , addr , "--force" )
2022-01-31 13:26:23 +00:00
actual , err := wallet . NewWalletFromFile ( walletPath )
2021-07-29 11:46:07 +00:00
require . NoError ( t , err )
2022-01-31 13:26:23 +00:00
require . Equal ( t , 1 , len ( actual . Accounts ) )
require . Equal ( t , w . Accounts [ 1 ] , actual . Accounts [ 0 ] )
2021-07-29 11:46:07 +00:00
}
2022-01-15 00:46:31 +00:00
func TestWalletChangePassword ( t * testing . T ) {
tmpDir := t . TempDir ( )
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , false )
2022-01-15 00:46:31 +00:00
walletPath := filepath . Join ( tmpDir , "wallet.json" )
e . In . WriteString ( "acc1\r" )
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass\r" )
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath , "--account" )
e . In . WriteString ( "acc2\r" )
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass\r" )
e . Run ( t , "neo-go" , "wallet" , "create" , "--wallet" , walletPath )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
addr1 := w . Accounts [ 0 ] . Address
addr2 := w . Accounts [ 1 ] . Address
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet path" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "change-password" )
} )
t . Run ( "EOF reading old password" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath )
} )
2022-01-15 00:46:31 +00:00
t . Run ( "bad old password" , func ( t * testing . T ) {
e . In . WriteString ( "ssap\r" )
e . In . WriteString ( "aaa\r" ) // Pretend for the password to be fine.
e . In . WriteString ( "aaa\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath )
} )
t . Run ( "no account" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath , "--address" , "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq" )
} )
t . Run ( "bad new password, multiaccount" , func ( t * testing . T ) {
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass1\r" )
e . In . WriteString ( "pass2\r" )
2024-07-04 22:34:40 +00:00
e . RunWithError ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath , "--address" , addr1 )
2022-01-15 00:46:31 +00:00
} )
t . Run ( "good, multiaccount" , func ( t * testing . T ) {
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "asdf\r" )
e . In . WriteString ( "asdf\r" )
e . Run ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath )
} )
t . Run ( "good, single account" , func ( t * testing . T ) {
e . In . WriteString ( "asdf\r" )
e . In . WriteString ( "jkl\r" )
e . In . WriteString ( "jkl\r" )
e . Run ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath , "--address" , addr1 )
} )
t . Run ( "bad, different passwords" , func ( t * testing . T ) {
e . In . WriteString ( "jkl\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath )
} )
t . Run ( "good, second account" , func ( t * testing . T ) {
e . In . WriteString ( "asdf\r" )
e . In . WriteString ( "jkl\r" )
e . In . WriteString ( "jkl\r" )
e . Run ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath , "--address" , addr2 )
} )
t . Run ( "good, second multiaccount" , func ( t * testing . T ) {
e . In . WriteString ( "jkl\r" )
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass\r" )
e . Run ( t , "neo-go" , "wallet" , "change-password" , "--wallet" , walletPath )
} )
}
2020-08-31 13:17:44 +00:00
func TestWalletInit ( t * testing . T ) {
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , false )
2020-08-31 13:17:44 +00:00
2022-01-31 13:26:23 +00:00
t . Run ( "missing path" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "init" )
} )
t . Run ( "invalid path" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "init" , "--wallet" , t . TempDir ( ) )
} )
t . Run ( "good: no account" , func ( t * testing . T ) {
walletPath := filepath . Join ( t . TempDir ( ) , "wallet.json" )
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Equal ( t , 0 , len ( w . Accounts ) )
} )
t . Run ( "with account" , func ( t * testing . T ) {
walletPath := filepath . Join ( t . TempDir ( ) , "wallet.json" )
t . Run ( "missing acc name" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath , "--account" )
} )
t . Run ( "missing pass" , func ( t * testing . T ) {
e . In . WriteString ( "acc\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath , "--account" )
} )
t . Run ( "missing second pass" , func ( t * testing . T ) {
e . In . WriteString ( "acc\r" )
e . In . WriteString ( "pass\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath , "--account" )
} )
e . In . WriteString ( "acc\r" )
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass\r" )
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath , "--account" )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( w . Accounts ) )
require . Equal ( t , "acc" , w . Accounts [ 0 ] . Label )
} )
2022-06-23 13:50:21 +00:00
t . Run ( "with wallet config" , func ( t * testing . T ) {
tmp := t . TempDir ( )
walletPath := filepath . Join ( tmp , "wallet.json" )
configPath := filepath . Join ( tmp , "config.yaml" )
cfg := config . Wallet {
Path : walletPath ,
Password : "pass" ,
}
res , err := yaml . Marshal ( cfg )
require . NoError ( t , err )
require . NoError ( t , os . WriteFile ( configPath , res , 0666 ) )
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet-config" , configPath , "--account" )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( w . Accounts ) )
require . Equal ( t , "" , w . Accounts [ 0 ] . Label )
} )
2022-01-31 13:26:23 +00:00
tmpDir := t . TempDir ( )
2021-11-17 11:14:22 +00:00
walletPath := filepath . Join ( tmpDir , "wallet.json" )
2020-08-31 13:17:44 +00:00
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath )
2021-02-10 08:53:01 +00:00
t . Run ( "terminal escape codes" , func ( t * testing . T ) {
2021-11-17 11:14:22 +00:00
walletPath := filepath . Join ( tmpDir , "walletrussian.json" )
2021-02-10 08:53:01 +00:00
bksp := string ( [ ] byte {
byte ( readline . CharBackward ) ,
byte ( readline . CharDelete ) ,
} )
e . In . WriteString ( "буквыы" +
bksp + bksp + bksp +
"andmore\r" )
e . In . WriteString ( "пароу" + bksp + "ль\r" )
e . In . WriteString ( "пароль\r" )
e . Run ( t , "neo-go" , "wallet" , "init" , "--account" ,
"--wallet" , walletPath )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Len ( t , w . Accounts , 1 )
require . Equal ( t , "букandmore" , w . Accounts [ 0 ] . Label )
2021-06-04 11:27:22 +00:00
require . NoError ( t , w . Accounts [ 0 ] . Decrypt ( "пароль" , w . Scrypt ) )
2021-02-10 08:53:01 +00:00
} )
2020-08-31 13:17:44 +00:00
t . Run ( "CreateAccount" , func ( t * testing . T ) {
2021-12-07 16:36:02 +00:00
t . Run ( "stdin" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "create" , "--wallet" , "-" )
} )
2022-01-31 13:26:23 +00:00
t . Run ( "passwords mismatch" , func ( t * testing . T ) {
e . In . WriteString ( "testname\r" )
e . In . WriteString ( "testpass\r" )
e . In . WriteString ( "badpass\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "create" , "--wallet" , walletPath )
} )
2020-08-31 13:17:44 +00:00
e . In . WriteString ( "testname\r" )
e . In . WriteString ( "testpass\r" )
e . In . WriteString ( "testpass\r" )
e . Run ( t , "neo-go" , "wallet" , "create" , "--wallet" , walletPath )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Len ( t , w . Accounts , 1 )
require . Equal ( t , w . Accounts [ 0 ] . Label , "testname" )
2021-06-04 11:27:22 +00:00
require . NoError ( t , w . Accounts [ 0 ] . Decrypt ( "testpass" , w . Scrypt ) )
2020-09-01 12:10:45 +00:00
t . Run ( "RemoveAccount" , func ( t * testing . T ) {
sh := w . Accounts [ 0 ] . Contract . ScriptHash ( )
addr := w . Accounts [ 0 ] . Address
e . In . WriteString ( "y\r" )
e . Run ( t , "neo-go" , "wallet" , "remove" ,
2021-04-19 13:45:40 +00:00
"--wallet" , walletPath , "--address" , addr )
2020-09-01 12:10:45 +00:00
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Nil ( t , w . GetAccount ( sh ) )
} )
2020-08-31 13:17:44 +00:00
} )
t . Run ( "Import" , func ( t * testing . T ) {
t . Run ( "WIF" , func ( t * testing . T ) {
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "import" )
} )
2020-08-31 13:17:44 +00:00
priv , err := keys . NewPrivateKey ( )
require . NoError ( t , err )
e . In . WriteString ( "test_account\r" )
e . In . WriteString ( "qwerty\r" )
e . In . WriteString ( "qwerty\r" )
e . Run ( t , "neo-go" , "wallet" , "import" , "--wallet" , walletPath ,
"--wif" , priv . WIF ( ) )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
acc := w . GetAccount ( priv . GetScriptHash ( ) )
require . NotNil ( t , acc )
require . Equal ( t , "test_account" , acc . Label )
2021-06-04 11:27:22 +00:00
require . NoError ( t , acc . Decrypt ( "qwerty" , w . Scrypt ) )
2020-08-31 13:17:44 +00:00
t . Run ( "AlreadyExists" , func ( t * testing . T ) {
e . In . WriteString ( "test_account_2\r" )
e . In . WriteString ( "qwerty2\r" )
e . In . WriteString ( "qwerty2\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "import" ,
"--wallet" , walletPath , "--wif" , priv . WIF ( ) )
} )
2022-01-31 13:26:23 +00:00
t . Run ( "contract" , func ( t * testing . T ) {
priv , err = keys . NewPrivateKey ( )
require . NoError ( t , err )
t . Run ( "invalid script" , func ( t * testing . T ) {
e . In . WriteString ( "test_account_3\r" )
e . In . WriteString ( "qwerty\r" )
e . In . WriteString ( "qwerty\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "import" ,
"--wallet" , walletPath , "--wif" , priv . WIF ( ) , "--contract" , "not-a-hex" )
} )
2022-06-23 13:50:21 +00:00
check := func ( t * testing . T , expectedLabel string , pass string ) {
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
acc := w . GetAccount ( priv . GetScriptHash ( ) )
require . NotNil ( t , acc )
require . Equal ( t , expectedLabel , acc . Label )
require . NoError ( t , acc . Decrypt ( pass , w . Scrypt ) )
}
t . Run ( "good" , func ( t * testing . T ) {
e . In . WriteString ( "test_account_3\r" )
e . In . WriteString ( "qwerty\r" )
e . In . WriteString ( "qwerty\r" )
e . Run ( t , "neo-go" , "wallet" , "import" ,
"--wallet" , walletPath , "--wif" , priv . WIF ( ) , "--contract" , "0a0b0c" )
check ( t , "test_account_3" , "qwerty" )
} )
2022-01-31 13:26:23 +00:00
2022-06-23 13:50:21 +00:00
t . Run ( "from wallet config" , func ( t * testing . T ) {
tmp := t . TempDir ( )
configPath := filepath . Join ( tmp , "config.yaml" )
cfg := config . Wallet {
Path : walletPath ,
2023-01-25 06:34:17 +00:00
Password : "qwerty" ,
2022-06-23 13:50:21 +00:00
}
res , err := yaml . Marshal ( cfg )
require . NoError ( t , err )
require . NoError ( t , os . WriteFile ( configPath , res , 0666 ) )
priv , err = keys . NewPrivateKey ( )
require . NoError ( t , err )
e . In . WriteString ( "test_account_4\r" )
e . Run ( t , "neo-go" , "wallet" , "import" ,
"--wallet-config" , configPath , "--wif" , priv . WIF ( ) , "--contract" , "0a0b0c0d" )
check ( t , "test_account_4" , "qwerty" )
} )
2023-01-25 06:34:17 +00:00
t . Run ( "from wallet config with account name argument" , func ( t * testing . T ) {
tmp := t . TempDir ( )
configPath := filepath . Join ( tmp , "config.yaml" )
cfg := config . Wallet {
Path : walletPath ,
Password : "qwerty" ,
}
res , err := yaml . Marshal ( cfg )
require . NoError ( t , err )
require . NoError ( t , os . WriteFile ( configPath , res , 0666 ) )
priv , err = keys . NewPrivateKey ( )
require . NoError ( t , err )
e . Run ( t , "neo-go" , "wallet" , "import" ,
"--wallet-config" , configPath , "--wif" , priv . WIF ( ) , "--contract" , "0a0b0c0d" , "--name" , "test_account_5" )
check ( t , "test_account_5" , "qwerty" )
} )
2022-01-31 13:26:23 +00:00
} )
2020-08-31 13:17:44 +00:00
} )
t . Run ( "EncryptedWIF" , func ( t * testing . T ) {
acc , err := wallet . NewAccount ( )
require . NoError ( t , err )
2021-06-04 11:27:22 +00:00
require . NoError ( t , acc . Encrypt ( "somepass" , keys . NEP2ScryptParams ( ) ) )
2020-08-31 13:17:44 +00:00
t . Run ( "InvalidPassword" , func ( t * testing . T ) {
e . In . WriteString ( "password1\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "import" , "--wallet" , walletPath ,
2023-01-26 04:11:57 +00:00
"--wif" , acc . EncryptedWIF , "--name" , "acc1" )
2020-08-31 13:17:44 +00:00
} )
2023-01-26 04:11:57 +00:00
e . In . WriteString ( "somepass\r" )
e . Run ( t , "neo-go" , "wallet" , "import" , "--wallet" , walletPath ,
"--wif" , acc . EncryptedWIF , "--name" , "acc1" )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
actual := w . GetAccount ( acc . PrivateKey ( ) . GetScriptHash ( ) )
require . NotNil ( t , actual )
require . Equal ( t , "acc1" , actual . Label )
require . NoError ( t , actual . Decrypt ( "somepass" , w . Scrypt ) )
} )
t . Run ( "EncryptedWIF with name specified via input" , func ( t * testing . T ) {
acc , err := wallet . NewAccount ( )
require . NoError ( t , err )
require . NoError ( t , acc . Encrypt ( "somepass" , keys . NEP2ScryptParams ( ) ) )
e . In . WriteString ( "acc2\r" )
2020-08-31 13:17:44 +00:00
e . In . WriteString ( "somepass\r" )
e . Run ( t , "neo-go" , "wallet" , "import" , "--wallet" , walletPath ,
"--wif" , acc . EncryptedWIF )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
actual := w . GetAccount ( acc . PrivateKey ( ) . GetScriptHash ( ) )
require . NotNil ( t , actual )
2023-01-26 04:11:57 +00:00
require . Equal ( t , "acc2" , actual . Label )
2021-06-04 11:27:22 +00:00
require . NoError ( t , actual . Decrypt ( "somepass" , w . Scrypt ) )
2020-08-31 13:17:44 +00:00
} )
2023-01-25 06:51:54 +00:00
t . Run ( "EncryptedWIF with wallet config" , func ( t * testing . T ) {
pass := "somepass"
check := func ( t * testing . T , configPass string , needUserPass bool ) {
acc , err := wallet . NewAccount ( )
require . NoError ( t , acc . Encrypt ( pass , keys . NEP2ScryptParams ( ) ) )
configPath := filepath . Join ( t . TempDir ( ) , "wallet-config.yaml" )
require . NoError ( t , err )
cfg := & config . Wallet {
Path : walletPath ,
Password : configPass ,
}
bytes , err := yaml . Marshal ( cfg )
require . NoError ( t , err )
require . NoError ( t , os . WriteFile ( configPath , bytes , os . ModePerm ) )
if needUserPass {
e . In . WriteString ( pass + "\r" )
}
e . Run ( t , "neo-go" , "wallet" , "import" , "--wallet-config" , configPath ,
2023-01-26 04:11:57 +00:00
"--wif" , acc . EncryptedWIF , "--name" , "acc3" + configPass )
2023-01-25 06:51:54 +00:00
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
actual := w . GetAccount ( acc . PrivateKey ( ) . GetScriptHash ( ) )
require . NotNil ( t , actual )
2023-01-26 04:11:57 +00:00
require . Equal ( t , "acc3" + configPass , actual . Label )
2023-01-25 06:51:54 +00:00
require . NoError ( t , actual . Decrypt ( pass , w . Scrypt ) )
}
t . Run ( "config password mismatch" , func ( t * testing . T ) {
check ( t , pass + "badpass" , true )
} )
t . Run ( "good config password" , func ( t * testing . T ) {
check ( t , pass , false )
} )
} )
2020-09-01 12:05:07 +00:00
t . Run ( "Multisig" , func ( t * testing . T ) {
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "import-multisig" )
} )
t . Run ( "insufficient pubs" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "import-multisig" ,
"--wallet" , walletPath ,
"--min" , "2" )
} )
2022-10-05 06:44:10 +00:00
privs , pubs := testcli . GenerateKeys ( t , 4 )
2020-09-01 12:05:07 +00:00
cmd := [ ] string { "neo-go" , "wallet" , "import-multisig" ,
"--wallet" , walletPath ,
"--min" , "2" }
2022-01-31 13:26:23 +00:00
t . Run ( "invalid pub encoding" , func ( t * testing . T ) {
2024-04-09 09:13:43 +00:00
e . RunWithError ( t , append ( cmd , pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 2 ] . StringCompressed ( ) ,
2022-01-31 13:26:23 +00:00
"not-a-pub" ) ... )
} )
t . Run ( "missing WIF" , func ( t * testing . T ) {
2024-04-09 09:13:43 +00:00
e . RunWithError ( t , append ( cmd , pubs [ 0 ] . StringCompressed ( ) ,
pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 2 ] . StringCompressed ( ) ,
pubs [ 3 ] . StringCompressed ( ) ) ... )
2022-01-31 13:26:23 +00:00
} )
cmd = append ( cmd , "--wif" , privs [ 0 ] . WIF ( ) )
2020-09-01 12:05:07 +00:00
t . Run ( "InvalidPublicKeys" , func ( t * testing . T ) {
e . In . WriteString ( "multiacc\r" )
e . In . WriteString ( "multipass\r" )
e . In . WriteString ( "multipass\r" )
defer e . In . Reset ( )
2024-04-09 09:13:43 +00:00
e . RunWithError ( t , append ( cmd , pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 2 ] . StringCompressed ( ) ,
pubs [ 3 ] . StringCompressed ( ) ) ... )
2020-09-01 12:05:07 +00:00
} )
e . In . WriteString ( "multiacc\r" )
e . In . WriteString ( "multipass\r" )
e . In . WriteString ( "multipass\r" )
2024-04-09 09:13:43 +00:00
e . Run ( t , append ( cmd , pubs [ 0 ] . StringCompressed ( ) ,
pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 2 ] . StringCompressed ( ) ,
pubs [ 3 ] . StringCompressed ( ) ) ... )
2020-09-01 12:05:07 +00:00
script , err := smartcontract . CreateMultiSigRedeemScript ( 2 , pubs )
require . NoError ( t , err )
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
actual := w . GetAccount ( hash . Hash160 ( script ) )
require . NotNil ( t , actual )
2021-06-04 11:27:22 +00:00
require . NoError ( t , actual . Decrypt ( "multipass" , w . Scrypt ) )
2020-09-01 12:05:07 +00:00
require . Equal ( t , script , actual . Contract . Script )
2022-01-31 13:26:23 +00:00
t . Run ( "double-import" , func ( t * testing . T ) {
e . In . WriteString ( "multiacc\r" )
e . In . WriteString ( "multipass\r" )
e . In . WriteString ( "multipass\r" )
2024-04-09 09:13:43 +00:00
e . RunWithError ( t , append ( cmd , pubs [ 0 ] . StringCompressed ( ) ,
pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 2 ] . StringCompressed ( ) ,
pubs [ 3 ] . StringCompressed ( ) ) ... )
2022-01-31 13:26:23 +00:00
} )
2024-01-18 20:47:40 +00:00
privs , pubs = testcli . GenerateKeys ( t , 3 )
script , err = smartcontract . CreateMultiSigRedeemScript ( 2 , pubs )
require . NoError ( t , err )
// Create a wallet and import a standard account
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath )
e . In . WriteString ( "standardacc\rstdpass\rstdpass\r" )
e . Run ( t , "neo-go" , "wallet" , "import" ,
"--wallet" , walletPath ,
"--wif" , privs [ 0 ] . WIF ( ) )
w , err = wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
actual = w . GetAccount ( privs [ 0 ] . GetScriptHash ( ) )
require . NotNil ( t , actual )
require . NotEqual ( t , actual . Contract . Script , script )
// Test when a public key of an already imported account is present
t . Run ( "existing account public key, no WIF" , func ( t * testing . T ) {
e . Run ( t , "neo-go" , "wallet" , "import-multisig" ,
"--wallet" , walletPath ,
"--min" , "2" ,
2024-04-09 09:13:43 +00:00
pubs [ 0 ] . StringCompressed ( ) , // Public key of the already imported account
pubs [ 1 ] . StringCompressed ( ) ,
pubs [ 2 ] . StringCompressed ( ) )
2024-01-18 20:47:40 +00:00
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
actual := w . GetAccount ( hash . Hash160 ( script ) )
require . NotNil ( t , actual )
require . Equal ( t , actual . Contract . Script , script )
require . NoError ( t , actual . Decrypt ( "stdpass" , w . Scrypt ) )
require . NotEqual ( t , actual . Address , w . GetAccount ( privs [ 0 ] . GetScriptHash ( ) ) . Address )
} )
// Test when no public key of an already imported account is present, and no WIF is provided
t . Run ( "no existing account public key, no WIF" , func ( t * testing . T ) {
_ , pubsNew := testcli . GenerateKeys ( t , 3 )
scriptNew , err := smartcontract . CreateMultiSigRedeemScript ( 2 , pubsNew )
require . NoError ( t , err )
e . RunWithError ( t , "neo-go" , "wallet" , "import-multisig" ,
"--wallet" , walletPath ,
"--min" , "2" ,
2024-04-09 09:13:43 +00:00
pubsNew [ 0 ] . StringCompressed ( ) ,
pubsNew [ 1 ] . StringCompressed ( ) ,
pubsNew [ 2 ] . StringCompressed ( ) )
2024-01-18 20:47:40 +00:00
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
actual := w . GetAccount ( hash . Hash160 ( scriptNew ) )
require . Nil ( t , actual )
} )
2020-09-01 12:05:07 +00:00
} )
2020-08-31 13:17:44 +00:00
} )
}
2020-09-01 11:55:10 +00:00
func TestWalletExport ( t * testing . T ) {
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , false )
2020-09-01 11:55:10 +00:00
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "export" )
} )
t . Run ( "invalid address" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "export" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "not-an-address" )
2022-01-31 13:26:23 +00:00
} )
2020-09-01 11:55:10 +00:00
t . Run ( "Encrypted" , func ( t * testing . T ) {
e . Run ( t , "neo-go" , "wallet" , "export" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , testcli . ValidatorAddr )
2020-09-01 11:55:10 +00:00
line , err := e . Out . ReadString ( '\n' )
require . NoError ( t , err )
2022-10-05 06:44:10 +00:00
enc , err := keys . NEP2Encrypt ( testcli . ValidatorPriv , "one" , keys . ScryptParams { N : 2 , R : 1 , P : 1 } ) // these params used in validator wallet for better resources consumption
2020-09-01 11:55:10 +00:00
require . NoError ( t , err )
require . Equal ( t , enc , strings . TrimSpace ( line ) )
} )
t . Run ( "Decrypted" , func ( t * testing . T ) {
t . Run ( "NoAddress" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "export" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "--decrypt" )
2020-09-01 11:55:10 +00:00
} )
2022-01-31 13:26:23 +00:00
t . Run ( "EOF reading password" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "export" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "--decrypt" , testcli . ValidatorAddr )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "invalid password" , func ( t * testing . T ) {
e . In . WriteString ( "invalid_pass\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "export" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "--decrypt" , testcli . ValidatorAddr )
2022-01-31 13:26:23 +00:00
} )
2020-09-01 11:55:10 +00:00
e . In . WriteString ( "one\r" )
e . Run ( t , "neo-go" , "wallet" , "export" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "--decrypt" , testcli . ValidatorAddr )
2020-09-01 11:55:10 +00:00
line , err := e . Out . ReadString ( '\n' )
require . NoError ( t , err )
2022-10-05 06:44:10 +00:00
require . Equal ( t , testcli . ValidatorWIF , strings . TrimSpace ( line ) )
2020-09-01 11:55:10 +00:00
} )
}
2020-09-02 08:43:25 +00:00
2022-01-31 13:26:23 +00:00
func TestWalletClaimGas ( t * testing . T ) {
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , true )
2020-09-02 08:43:25 +00:00
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet path" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "claim" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--address" , testcli . TestWalletAccount )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "missing address" , func ( t * testing . T ) {
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "address" not set ` , "neo-go" , "wallet" , "claim" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . TestWalletPath )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "invalid address" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "claim" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . TestWalletPath ,
2022-01-31 13:26:23 +00:00
"--address" , util . Uint160 { } . StringLE ( ) )
} )
t . Run ( "missing endpoint" , func ( t * testing . T ) {
e . In . WriteString ( "testpass\r" )
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "rpc-endpoint" not set ` , "neo-go" , "wallet" , "claim" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . TestWalletPath ,
"--address" , testcli . TestWalletAccount )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "insufficient funds" , func ( t * testing . T ) {
e . In . WriteString ( "testpass\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "claim" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . TestWalletPath ,
"--address" , testcli . TestWalletAccount )
2022-01-31 13:26:23 +00:00
} )
2020-11-06 09:27:05 +00:00
args := [ ] string {
2020-11-24 08:14:25 +00:00
"neo-go" , "wallet" , "nep17" , "multitransfer" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet ,
"--from" , testcli . ValidatorAddr ,
2021-09-15 09:40:30 +00:00
"--force" ,
2022-10-05 06:44:10 +00:00
"NEO:" + testcli . TestWalletAccount + ":1000" ,
"GAS:" + testcli . TestWalletAccount + ":1000" , // for tx send
2020-11-06 09:27:05 +00:00
}
e . In . WriteString ( "one\r" )
e . Run ( t , args ... )
2022-10-05 06:44:10 +00:00
e . CheckTxPersisted ( t )
2020-11-06 09:27:05 +00:00
2022-10-05 06:44:10 +00:00
h , err := address . StringToUint160 ( testcli . TestWalletAccount )
2020-11-06 09:27:05 +00:00
require . NoError ( t , err )
balanceBefore := e . Chain . GetUtilityTokenBalance ( h )
claimHeight := e . Chain . BlockHeight ( ) + 1
cl , err := e . Chain . CalculateClaimable ( h , claimHeight )
require . NoError ( t , err )
2020-09-02 08:43:25 +00:00
require . True ( t , cl . Sign ( ) > 0 )
2020-11-06 09:27:05 +00:00
e . In . WriteString ( "testpass\r" )
e . Run ( t , "neo-go" , "wallet" , "claim" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . TestWalletPath ,
2022-10-06 19:19:40 +00:00
"--address" , testcli . TestWalletAccount ,
"--force" )
2022-10-05 06:44:10 +00:00
tx , height := e . CheckTxPersisted ( t )
2020-11-06 09:27:05 +00:00
balanceBefore . Sub ( balanceBefore , big . NewInt ( tx . NetworkFee + tx . SystemFee ) )
balanceBefore . Add ( balanceBefore , cl )
balanceAfter := e . Chain . GetUtilityTokenBalance ( h )
// height can be bigger than claimHeight especially when tests are executed with -race.
if height == claimHeight {
require . Equal ( t , 0 , balanceAfter . Cmp ( balanceBefore ) )
} else {
require . Equal ( t , 1 , balanceAfter . Cmp ( balanceBefore ) )
}
2023-12-28 11:58:38 +00:00
t . Run ( "await" , func ( t * testing . T ) {
args := [ ] string {
"neo-go" , "wallet" , "nep17" , "multitransfer" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
"--wallet" , testcli . ValidatorWallet ,
"--from" , testcli . ValidatorAddr , "--await" ,
"--force" ,
"NEO:" + testcli . TestWalletAccount + ":1000" ,
"GAS:" + testcli . TestWalletAccount + ":1000" , // for tx send
}
e . In . WriteString ( "one\r" )
e . Run ( t , args ... )
e . CheckAwaitableTxPersisted ( t )
h , err := address . StringToUint160 ( testcli . TestWalletAccount )
require . NoError ( t , err )
balanceBefore := e . Chain . GetUtilityTokenBalance ( h )
claimHeight := e . Chain . BlockHeight ( ) + 1
cl , err := e . Chain . CalculateClaimable ( h , claimHeight )
require . NoError ( t , err )
require . True ( t , cl . Sign ( ) > 0 )
e . In . WriteString ( "testpass\r" )
e . Run ( t , "neo-go" , "wallet" , "claim" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
"--wallet" , testcli . TestWalletPath ,
"--address" , testcli . TestWalletAccount ,
"--force" , "--await" )
tx , height = e . CheckAwaitableTxPersisted ( t )
balanceBefore . Sub ( balanceBefore , big . NewInt ( tx . NetworkFee + tx . SystemFee ) )
balanceBefore . Add ( balanceBefore , cl )
balanceAfter = e . Chain . GetUtilityTokenBalance ( h )
// height can be bigger than claimHeight especially when tests are executed with -race.
if height == claimHeight {
require . Equal ( t , 0 , balanceAfter . Cmp ( balanceBefore ) )
} else {
require . Equal ( t , 1 , balanceAfter . Cmp ( balanceBefore ) )
}
} )
2020-09-02 08:43:25 +00:00
}
2020-09-02 09:20:42 +00:00
2022-01-31 13:26:23 +00:00
func TestWalletImportDeployed ( t * testing . T ) {
2021-08-25 19:17:37 +00:00
tmpDir := t . TempDir ( )
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , true )
2021-04-22 12:14:02 +00:00
h := deployVerifyContract ( t , e )
2021-11-17 11:14:22 +00:00
walletPath := filepath . Join ( tmpDir , "wallet.json" )
2021-08-25 19:17:37 +00:00
2021-07-20 09:32:02 +00:00
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath )
2020-09-02 09:20:42 +00:00
priv , err := keys . NewPrivateKey ( )
require . NoError ( t , err )
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet" , func ( t * testing . T ) {
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "contract" not set ` , "neo-go" , "wallet" , "import-deployed" , "--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "missing contract sh" , func ( t * testing . T ) {
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "contract" not set ` , "neo-go" , "wallet" , "import-deployed" ,
"--wallet" , walletPath , "--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "missing WIF" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "import-deployed" ,
2024-07-04 22:34:40 +00:00
"--wallet" , walletPath , "--contract" , h . StringLE ( ) , "--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "missing endpoint" , func ( t * testing . T ) {
e . In . WriteString ( "acc\rpass\rpass\r" )
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "rpc-endpoint" not set ` , "neo-go" , "wallet" , "import-deployed" ,
2022-01-31 13:26:23 +00:00
"--wallet" , walletPath , "--contract" , h . StringLE ( ) ,
"--wif" , priv . WIF ( ) )
} )
t . Run ( "unknown contract" , func ( t * testing . T ) {
e . In . WriteString ( "acc\rpass\rpass\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "import-deployed" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-01-31 13:26:23 +00:00
"--wallet" , walletPath , "--contract" , util . Uint160 { } . StringLE ( ) ,
"--wif" , priv . WIF ( ) )
} )
t . Run ( "no `verify` method" , func ( t * testing . T ) {
badH := deployNNSContract ( t , e ) // wrong contract with no `verify` method
e . In . WriteString ( "acc\rpass\rpass\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "import-deployed" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-01-31 13:26:23 +00:00
"--wallet" , walletPath , "--contract" , badH . StringLE ( ) ,
"--wif" , priv . WIF ( ) )
} )
2021-04-16 09:23:46 +00:00
2020-09-02 09:20:42 +00:00
e . In . WriteString ( "acc\rpass\rpass\r" )
e . Run ( t , "neo-go" , "wallet" , "import-deployed" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2023-01-25 06:34:17 +00:00
"--wallet" , walletPath , "--wif" , priv . WIF ( ) ,
2020-09-02 09:20:42 +00:00
"--contract" , h . StringLE ( ) )
2023-01-25 06:34:17 +00:00
contractAddr := address . Uint160ToString ( h )
checkDeployed := func ( t * testing . T ) {
w , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( w . Accounts ) )
actualAddr := w . Accounts [ 0 ] . Address
require . Equal ( t , contractAddr , actualAddr )
require . True ( t , w . Accounts [ 0 ] . Contract . Deployed )
}
checkDeployed ( t )
2020-09-02 09:20:42 +00:00
2022-01-31 13:26:23 +00:00
t . Run ( "re-importing" , func ( t * testing . T ) {
e . In . WriteString ( "acc\rpass\rpass\r" )
e . RunWithError ( t , "neo-go" , "wallet" , "import-deployed" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2023-01-25 06:34:17 +00:00
"--wallet" , walletPath , "--wif" , priv . WIF ( ) ,
2022-01-31 13:26:23 +00:00
"--contract" , h . StringLE ( ) )
} )
2020-09-02 09:20:42 +00:00
t . Run ( "Sign" , func ( t * testing . T ) {
e . In . WriteString ( "one\r" )
2020-11-24 08:14:25 +00:00
e . Run ( t , "neo-go" , "wallet" , "nep17" , "multitransfer" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "--from" , testcli . ValidatorAddr ,
2021-09-15 09:40:30 +00:00
"--force" ,
2020-12-13 18:05:49 +00:00
"NEO:" + contractAddr + ":10" ,
"GAS:" + contractAddr + ":10" )
2022-10-05 06:44:10 +00:00
e . CheckTxPersisted ( t )
2020-09-02 09:20:42 +00:00
privTo , err := keys . NewPrivateKey ( )
require . NoError ( t , err )
e . In . WriteString ( "pass\r" )
2020-11-24 08:14:25 +00:00
e . Run ( t , "neo-go" , "wallet" , "nep17" , "transfer" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2020-09-02 09:20:42 +00:00
"--wallet" , walletPath , "--from" , contractAddr ,
2021-09-15 09:40:30 +00:00
"--force" ,
2020-12-13 18:05:49 +00:00
"--to" , privTo . Address ( ) , "--token" , "NEO" , "--amount" , "1" )
2022-10-05 06:44:10 +00:00
e . CheckTxPersisted ( t )
2020-09-02 09:20:42 +00:00
b , _ := e . Chain . GetGoverningTokenBalance ( h )
require . Equal ( t , big . NewInt ( 9 ) , b )
b , _ = e . Chain . GetGoverningTokenBalance ( privTo . GetScriptHash ( ) )
require . Equal ( t , big . NewInt ( 1 ) , b )
} )
2023-01-25 06:34:17 +00:00
t . Run ( "import with name argument" , func ( t * testing . T ) {
e . Run ( t , "neo-go" , "wallet" , "remove" ,
"--wallet" , walletPath , "--address" , address . Uint160ToString ( h ) , "--force" )
e . In . WriteString ( "pass\rpass\r" )
e . Run ( t , "neo-go" , "wallet" , "import-deployed" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
"--wallet" , walletPath , "--wif" , priv . WIF ( ) ,
"--contract" , h . StringLE ( ) , "--name" , "acc" )
checkDeployed ( t )
} )
t . Run ( "import with name argument and wallet config" , func ( t * testing . T ) {
e . Run ( t , "neo-go" , "wallet" , "remove" ,
"--wallet" , walletPath , "--address" , address . Uint160ToString ( h ) , "--force" )
configPath := filepath . Join ( t . TempDir ( ) , "wallet-config.yaml" )
cfg := & config . Wallet {
Path : walletPath ,
Password : "pass" ,
}
bytes , err := yaml . Marshal ( cfg )
require . NoError ( t , err )
require . NoError ( t , os . WriteFile ( configPath , bytes , os . ModePerm ) )
e . Run ( t , "neo-go" , "wallet" , "import-deployed" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
"--wallet-config" , configPath , "--wif" , priv . WIF ( ) ,
"--contract" , h . StringLE ( ) , "--name" , "acc" )
checkDeployed ( t )
} )
2020-09-02 09:20:42 +00:00
}
2020-09-02 10:17:13 +00:00
2022-08-31 18:12:08 +00:00
func TestStripKeys ( t * testing . T ) {
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , true )
2022-08-31 18:12:08 +00:00
tmpDir := t . TempDir ( )
walletPath := filepath . Join ( tmpDir , "wallet.json" )
e . In . WriteString ( "acc1\r" )
e . In . WriteString ( "pass\r" )
e . In . WriteString ( "pass\r" )
e . Run ( t , "neo-go" , "wallet" , "init" , "--wallet" , walletPath , "--account" )
w1 , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
e . RunWithError ( t , "neo-go" , "wallet" , "strip-keys" , "--wallet" , walletPath , "something" )
e . RunWithError ( t , "neo-go" , "wallet" , "strip-keys" , "--wallet" , walletPath + ".bad" )
e . In . WriteString ( "no" )
e . Run ( t , "neo-go" , "wallet" , "strip-keys" , "--wallet" , walletPath )
w2 , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
require . Equal ( t , w1 , w2 )
e . In . WriteString ( "y\r" )
e . Run ( t , "neo-go" , "wallet" , "strip-keys" , "--wallet" , walletPath )
e . Run ( t , "neo-go" , "wallet" , "strip-keys" , "--wallet" , walletPath , "--force" ) // Does nothing effectively, but tests the force flag.
w3 , err := wallet . NewWalletFromFile ( walletPath )
require . NoError ( t , err )
for _ , a := range w3 . Accounts {
require . Equal ( t , "" , a . EncryptedWIF )
}
}
2022-08-31 19:38:35 +00:00
func TestOfflineSigning ( t * testing . T ) {
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , true )
2022-08-31 19:38:35 +00:00
tmpDir := t . TempDir ( )
walletPath := filepath . Join ( tmpDir , "wallet.json" )
txPath := filepath . Join ( tmpDir , "tx.json" )
// Copy wallet.
2022-10-05 06:44:10 +00:00
w , err := wallet . NewWalletFromFile ( testcli . ValidatorWallet )
2022-08-31 19:38:35 +00:00
require . NoError ( t , err )
jOut , err := w . JSON ( )
require . NoError ( t , err )
require . NoError ( t , os . WriteFile ( walletPath , jOut , 0644 ) )
// And remove keys from it.
e . Run ( t , "neo-go" , "wallet" , "strip-keys" , "--wallet" , walletPath , "--force" )
t . Run ( "1/1 multisig" , func ( t * testing . T ) {
args := [ ] string { "neo-go" , "wallet" , "nep17" , "transfer" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-08-31 19:38:35 +00:00
"--wallet" , walletPath ,
2022-10-05 06:44:10 +00:00
"--from" , testcli . ValidatorAddr ,
2022-08-31 19:38:35 +00:00
"--to" , w . Accounts [ 0 ] . Address ,
"--token" , "NEO" ,
"--amount" , "1" ,
"--force" ,
}
// walletPath has no keys, so this can't be sent.
e . RunWithError ( t , args ... )
// But can be saved.
e . Run ( t , append ( args , "--out" , txPath ) ... )
// It can't be signed with the original wallet.
e . RunWithError ( t , "neo-go" , "wallet" , "sign" ,
2022-10-05 06:44:10 +00:00
"--wallet" , walletPath , "--address" , testcli . ValidatorAddr ,
2022-08-31 19:38:35 +00:00
"--in" , txPath , "--out" , txPath )
t . Run ( "sendtx" , func ( t * testing . T ) {
// And it can't be sent.
e . RunWithError ( t , "neo-go" , "util" , "sendtx" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-08-31 19:38:35 +00:00
txPath )
// Even with too many arguments.
e . RunWithError ( t , "neo-go" , "util" , "sendtx" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-08-31 19:38:35 +00:00
txPath , txPath )
// Or no arguments at all.
e . RunWithError ( t , "neo-go" , "util" , "sendtx" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] )
2022-08-31 19:38:35 +00:00
} )
// But it can be signed with a proper wallet.
e . In . WriteString ( "one\r" )
e . Run ( t , "neo-go" , "wallet" , "sign" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "--address" , testcli . ValidatorAddr ,
2022-08-31 19:38:35 +00:00
"--in" , txPath , "--out" , txPath )
// And then anyone can send (even via wallet sign).
e . Run ( t , "neo-go" , "wallet" , "sign" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-10-05 06:44:10 +00:00
"--wallet" , walletPath , "--address" , testcli . ValidatorAddr ,
2022-08-31 19:38:35 +00:00
"--in" , txPath )
} )
2022-10-05 06:44:10 +00:00
e . CheckTxPersisted ( t )
2023-12-28 11:58:38 +00:00
t . Run ( "await 1/1 multisig" , func ( t * testing . T ) {
args := [ ] string { "neo-go" , "wallet" , "nep17" , "transfer" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
"--wallet" , walletPath ,
"--from" , testcli . ValidatorAddr ,
"--to" , w . Accounts [ 0 ] . Address ,
"--token" , "NEO" ,
"--amount" , "1" ,
"--force" ,
}
e . Run ( t , append ( args , "--out" , txPath ) ... )
e . In . WriteString ( "one\r" )
e . Run ( t , "neo-go" , "wallet" , "sign" ,
"--wallet" , testcli . ValidatorWallet , "--address" , testcli . ValidatorAddr ,
"--in" , txPath , "--out" , txPath )
e . Run ( t , "neo-go" , "wallet" , "sign" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
"--wallet" , walletPath , "--address" , testcli . ValidatorAddr ,
"--in" , txPath , "--await" )
e . CheckAwaitableTxPersisted ( t )
} )
2022-08-31 19:38:35 +00:00
t . Run ( "simple signature" , func ( t * testing . T ) {
simpleAddr := w . Accounts [ 0 ] . Address
args := [ ] string { "neo-go" , "wallet" , "nep17" , "transfer" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-08-31 19:38:35 +00:00
"--wallet" , walletPath ,
"--from" , simpleAddr ,
2022-10-05 06:44:10 +00:00
"--to" , testcli . ValidatorAddr ,
2022-08-31 19:38:35 +00:00
"--token" , "NEO" ,
"--amount" , "1" ,
"--force" ,
}
// walletPath has no keys, so this can't be sent.
e . RunWithError ( t , args ... )
// But can be saved.
e . Run ( t , append ( args , "--out" , txPath ) ... )
// It can't be signed with the original wallet.
e . RunWithError ( t , "neo-go" , "wallet" , "sign" ,
"--wallet" , walletPath , "--address" , simpleAddr ,
"--in" , txPath , "--out" , txPath )
// But can be with a proper one.
e . In . WriteString ( "one\r" )
e . Run ( t , "neo-go" , "wallet" , "sign" ,
2022-10-05 06:44:10 +00:00
"--wallet" , testcli . ValidatorWallet , "--address" , simpleAddr ,
2022-08-31 19:38:35 +00:00
"--in" , txPath , "--out" , txPath )
// Sending without an RPC node is not likely to succeed.
e . RunWithError ( t , "neo-go" , "util" , "sendtx" , txPath )
// But it requires no wallet at all.
e . Run ( t , "neo-go" , "util" , "sendtx" ,
2022-11-25 10:20:53 +00:00
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2022-08-31 19:38:35 +00:00
txPath )
} )
2023-12-28 11:58:38 +00:00
t . Run ( "await simple signature" , func ( t * testing . T ) {
simpleAddr := w . Accounts [ 0 ] . Address
args := [ ] string { "neo-go" , "wallet" , "nep17" , "transfer" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
"--wallet" , walletPath ,
"--from" , simpleAddr ,
"--to" , testcli . ValidatorAddr ,
"--token" , "NEO" ,
"--amount" , "1" ,
"--force" ,
}
e . Run ( t , append ( args , "--out" , txPath ) ... )
e . In . WriteString ( "one\r" )
e . Run ( t , "neo-go" , "wallet" , "sign" ,
"--wallet" , testcli . ValidatorWallet , "--address" , simpleAddr ,
"--in" , txPath , "--out" , txPath )
e . Run ( t , "neo-go" , "util" , "sendtx" ,
"--rpc-endpoint" , "http://" + e . RPC . Addresses ( ) [ 0 ] ,
2024-07-09 18:24:39 +00:00
"--await" , txPath )
2023-12-28 11:58:38 +00:00
e . CheckAwaitableTxPersisted ( t )
} )
2022-08-31 19:38:35 +00:00
}
2020-09-02 10:17:13 +00:00
func TestWalletDump ( t * testing . T ) {
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , false )
2020-09-02 10:17:13 +00:00
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "dump" )
} )
2022-10-05 06:44:10 +00:00
cmd := [ ] string { "neo-go" , "wallet" , "dump" , "--wallet" , testcli . TestWalletPath }
2020-12-03 14:30:09 +00:00
e . Run ( t , cmd ... )
2020-09-02 10:17:13 +00:00
rawStr := strings . TrimSpace ( e . Out . String ( ) )
w := new ( wallet . Wallet )
require . NoError ( t , json . Unmarshal ( [ ] byte ( rawStr ) , w ) )
require . Equal ( t , 1 , len ( w . Accounts ) )
2022-10-05 06:44:10 +00:00
require . Equal ( t , testcli . TestWalletAccount , w . Accounts [ 0 ] . Address )
2020-12-03 14:30:09 +00:00
t . Run ( "with decrypt" , func ( t * testing . T ) {
cmd = append ( cmd , "--decrypt" )
2022-01-31 13:26:23 +00:00
t . Run ( "EOF reading password" , func ( t * testing . T ) {
e . RunWithError ( t , cmd ... )
} )
2020-12-03 14:30:09 +00:00
t . Run ( "invalid password" , func ( t * testing . T ) {
e . In . WriteString ( "invalidpass\r" )
e . RunWithError ( t , cmd ... )
} )
2022-06-23 13:50:21 +00:00
t . Run ( "good" , func ( t * testing . T ) {
e . In . WriteString ( "testpass\r" )
e . Run ( t , cmd ... )
rawStr := strings . TrimSpace ( e . Out . String ( ) )
w := new ( wallet . Wallet )
require . NoError ( t , json . Unmarshal ( [ ] byte ( rawStr ) , w ) )
require . Equal ( t , 1 , len ( w . Accounts ) )
2022-10-05 06:44:10 +00:00
require . Equal ( t , testcli . TestWalletAccount , w . Accounts [ 0 ] . Address )
2022-06-23 13:50:21 +00:00
} )
t . Run ( "good, from wallet config" , func ( t * testing . T ) {
tmp := t . TempDir ( )
configPath := filepath . Join ( tmp , "config.yaml" )
cfg := config . Wallet {
2022-10-05 06:44:10 +00:00
Path : testcli . TestWalletPath ,
2022-06-23 13:50:21 +00:00
Password : "testpass" ,
}
res , err := yaml . Marshal ( cfg )
require . NoError ( t , err )
require . NoError ( t , os . WriteFile ( configPath , res , 0666 ) )
e . Run ( t , "neo-go" , "wallet" , "dump" , "--wallet-config" , configPath )
rawStr := strings . TrimSpace ( e . Out . String ( ) )
w := new ( wallet . Wallet )
require . NoError ( t , json . Unmarshal ( [ ] byte ( rawStr ) , w ) )
require . Equal ( t , 1 , len ( w . Accounts ) )
2022-10-05 06:44:10 +00:00
require . Equal ( t , testcli . TestWalletAccount , w . Accounts [ 0 ] . Address )
2022-06-23 13:50:21 +00:00
} )
2020-12-03 14:30:09 +00:00
} )
2020-09-02 10:17:13 +00:00
}
2020-12-03 14:33:52 +00:00
2022-01-31 13:26:23 +00:00
func TestWalletDumpKeys ( t * testing . T ) {
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , false )
2022-01-31 13:26:23 +00:00
t . Run ( "missing wallet" , func ( t * testing . T ) {
e . RunWithError ( t , "neo-go" , "wallet" , "dump-keys" )
} )
2022-10-05 06:44:10 +00:00
cmd := [ ] string { "neo-go" , "wallet" , "dump-keys" , "--wallet" , testcli . ValidatorWallet }
2021-03-05 09:23:25 +00:00
pubRegex := "^0[23][a-hA-H0-9]{64}$"
t . Run ( "all" , func ( t * testing . T ) {
e . Run ( t , cmd ... )
2022-10-05 06:44:10 +00:00
e . CheckNextLine ( t , "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn" )
e . CheckNextLine ( t , pubRegex )
e . CheckNextLine ( t , "^\\s*$" )
e . CheckNextLine ( t , "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq" )
2021-03-05 09:23:25 +00:00
for i := 0 ; i < 4 ; i ++ {
2022-10-05 06:44:10 +00:00
e . CheckNextLine ( t , pubRegex )
2021-03-05 09:23:25 +00:00
}
2022-10-05 06:44:10 +00:00
e . CheckNextLine ( t , "^\\s*$" )
e . CheckNextLine ( t , "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP" )
e . CheckNextLine ( t , pubRegex )
e . CheckEOF ( t )
2021-03-05 09:23:25 +00:00
} )
2022-01-31 13:26:23 +00:00
t . Run ( "unknown address" , func ( t * testing . T ) {
cmd := append ( cmd , "--address" , util . Uint160 { } . StringLE ( ) )
e . RunWithError ( t , cmd ... )
} )
2021-03-05 09:23:25 +00:00
t . Run ( "simple signature" , func ( t * testing . T ) {
2021-05-11 13:32:09 +00:00
cmd := append ( cmd , "--address" , "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn" )
2021-03-05 09:23:25 +00:00
e . Run ( t , cmd ... )
2022-10-05 06:44:10 +00:00
e . CheckNextLine ( t , "simple signature contract" )
e . CheckNextLine ( t , pubRegex )
e . CheckEOF ( t )
2021-03-05 09:23:25 +00:00
} )
t . Run ( "3/4 multisig" , func ( t * testing . T ) {
2021-05-11 14:13:33 +00:00
cmd := append ( cmd , "-a" , "NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq" )
2021-03-05 09:23:25 +00:00
e . Run ( t , cmd ... )
2022-10-05 06:44:10 +00:00
e . CheckNextLine ( t , "3 out of 4 multisig contract" )
2021-03-05 09:23:25 +00:00
for i := 0 ; i < 4 ; i ++ {
2022-10-05 06:44:10 +00:00
e . CheckNextLine ( t , pubRegex )
2021-03-05 09:23:25 +00:00
}
2022-10-05 06:44:10 +00:00
e . CheckEOF ( t )
2021-03-05 09:23:25 +00:00
} )
t . Run ( "1/1 multisig" , func ( t * testing . T ) {
2021-05-11 14:13:33 +00:00
cmd := append ( cmd , "--address" , "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP" )
2021-03-05 09:23:25 +00:00
e . Run ( t , cmd ... )
2022-10-05 06:44:10 +00:00
e . CheckNextLine ( t , "1 out of 1 multisig contract" )
e . CheckNextLine ( t , pubRegex )
e . CheckEOF ( t )
2021-03-05 09:23:25 +00:00
} )
}
2020-12-03 14:33:52 +00:00
// Testcase is the wallet of privnet validator.
func TestWalletConvert ( t * testing . T ) {
2021-08-25 19:17:37 +00:00
tmpDir := t . TempDir ( )
2022-10-05 06:44:10 +00:00
e := testcli . NewExecutor ( t , false )
2020-12-03 14:33:52 +00:00
2021-11-17 11:14:22 +00:00
outPath := filepath . Join ( tmpDir , "wallet.json" )
2020-12-03 14:33:52 +00:00
cmd := [ ] string { "neo-go" , "wallet" , "convert" }
t . Run ( "missing wallet" , func ( t * testing . T ) {
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "out" not set ` , cmd ... )
2020-12-03 14:33:52 +00:00
} )
2022-10-05 06:44:10 +00:00
cmd = append ( cmd , "--wallet" , "testdata/testwallet_NEO2.json" )
2022-01-31 13:26:23 +00:00
t . Run ( "missing out path" , func ( t * testing . T ) {
2024-07-04 22:34:40 +00:00
e . RunWithErrorCheck ( t , ` Required flag "out" not set ` , cmd ... )
2022-01-31 13:26:23 +00:00
} )
t . Run ( "invalid out path" , func ( t * testing . T ) {
dir := t . TempDir ( )
e . RunWithError ( t , append ( cmd , "--out" , dir ) ... )
} )
2020-12-03 14:33:52 +00:00
2022-01-31 13:26:23 +00:00
cmd = append ( cmd , "--out" , outPath )
2020-12-03 14:33:52 +00:00
t . Run ( "invalid password" , func ( t * testing . T ) {
// missing password
e . RunWithError ( t , cmd ... )
// invalid password
e . In . WriteString ( "two\r" )
e . RunWithError ( t , cmd ... )
} )
// 2 accounts.
e . In . WriteString ( "one\r" )
e . In . WriteString ( "one\r" )
e . Run ( t , "neo-go" , "wallet" , "convert" ,
2022-10-05 06:44:10 +00:00
"--wallet" , "testdata/testwallet_NEO2.json" ,
2020-12-03 14:33:52 +00:00
"--out" , outPath )
actual , err := wallet . NewWalletFromFile ( outPath )
require . NoError ( t , err )
2022-10-05 06:44:10 +00:00
expected , err := wallet . NewWalletFromFile ( "testdata/testwallet_NEO3.json" )
2020-12-03 14:33:52 +00:00
require . NoError ( t , err )
require . Equal ( t , len ( actual . Accounts ) , len ( expected . Accounts ) )
for _ , exp := range expected . Accounts {
addr , err := address . StringToUint160 ( exp . Address )
require . NoError ( t , err )
act := actual . GetAccount ( addr )
require . NotNil ( t , act )
require . Equal ( t , exp , act )
}
}
2022-10-05 15:06:06 +00:00
func deployNNSContract ( t * testing . T , e * testcli . Executor ) util . Uint160 {
return testcli . DeployContract ( t , e , "../../examples/nft-nd-nns/" , "../../examples/nft-nd-nns/nns.yml" , testcli . ValidatorWallet , testcli . ValidatorAddr , testcli . ValidatorPass )
}