cli: add tests for wallet import-deployed

Fix bugs with import, allow to sign tx with contract.
This commit is contained in:
Evgenii Stratonikov 2020-09-02 12:20:42 +03:00
parent 583ef546f9
commit 40a24bad64
7 changed files with 83 additions and 3 deletions

View file

@ -681,7 +681,6 @@ func getAccFromContext(ctx *cli.Context) (*wallet.Account, error) {
rawPass, err := input.ReadPassword(ctx.App.Writer, rawPass, err := input.ReadPassword(ctx.App.Writer,
fmt.Sprintf("Enter account %s password > ", address.Uint160ToString(addr))) fmt.Sprintf("Enter account %s password > ", address.Uint160ToString(addr)))
fmt.Fprintln(ctx.App.Writer)
if err != nil { if err != nil {
return nil, cli.NewExitError(err, 1) return nil, cli.NewExitError(err, 1)
} }
@ -750,7 +749,8 @@ func contractDeploy(ctx *cli.Context) error {
if err != nil { if err != nil {
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1) return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1)
} }
fmt.Fprintf(ctx.App.Writer, "Sent deployment transaction %s for contract %s\n", txHash.StringLE(), nefFile.Header.ScriptHash.StringLE()) fmt.Fprintf(ctx.App.Writer, "Contract: %s\n", nefFile.Header.ScriptHash.StringLE())
fmt.Fprintln(ctx.App.Writer, txHash.StringLE())
return nil return nil
} }

5
cli/testdata/verify.go vendored Normal file
View file

@ -0,0 +1,5 @@
package testdata
func Verify() bool {
return true
}

1
cli/testdata/verify.manifest.json vendored Executable file
View file

@ -0,0 +1 @@
{"abi":{"hash":"0x8dff9f223e4622961f410c015dd37052a59892bb","methods":[{"name":"verify","offset":0,"parameters":[],"returntype":"Boolean"}],"events":[]},"groups":[],"features":{"payable":true,"storage":false},"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":[],"trusts":[],"safemethods":[],"extra":null}

BIN
cli/testdata/verify.nef vendored Executable file

Binary file not shown.

View file

@ -407,7 +407,7 @@ func importDeployed(ctx *cli.Context) error {
defer wall.Close() defer wall.Close()
rawHash := strings.TrimPrefix("0x", ctx.String("contract")) rawHash := strings.TrimPrefix(ctx.String("contract"), "0x")
h, err := util.Uint160DecodeStringLE(rawHash) h, err := util.Uint160DecodeStringLE(rawHash)
if err != nil { if err != nil {
return cli.NewExitError(fmt.Errorf("invalid contract hash: %w", err), 1) return cli.NewExitError(fmt.Errorf("invalid contract hash: %w", err), 1)
@ -434,7 +434,9 @@ func importDeployed(ctx *cli.Context) error {
if md == nil { if md == nil {
return cli.NewExitError("contract has no `verify` method", 1) return cli.NewExitError("contract has no `verify` method", 1)
} }
acc.Address = address.Uint160ToString(cs.ScriptHash())
acc.Contract.Script = cs.Script acc.Contract.Script = cs.Script
acc.Contract.Parameters = acc.Contract.Parameters[:0]
for _, p := range md.Parameters { for _, p := range md.Parameters {
acc.Contract.Parameters = append(acc.Contract.Parameters, wallet.ContractParam{ acc.Contract.Parameters = append(acc.Contract.Parameters, wallet.ContractParam{
Name: p.Name, Name: p.Name,

View file

@ -10,7 +10,9 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "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/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/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -185,3 +187,69 @@ func TestClaimGas(t *testing.T) {
balanceAfter := e.Chain.GetUtilityTokenBalance(validatorHash) balanceAfter := e.Chain.GetUtilityTokenBalance(validatorHash)
require.Equal(t, 0, balanceAfter.Cmp(balanceBefore.Add(balanceBefore, cl))) require.Equal(t, 0, balanceAfter.Cmp(balanceBefore.Add(balanceBefore, cl)))
} }
func TestImportDeployed(t *testing.T) {
e := newExecutor(t, true)
defer e.Close(t)
e.In.WriteString("one\r")
e.Run(t, "neo-go", "contract", "deploy",
"--unittest", "--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--in", "testdata/verify.nef", "--manifest", "testdata/verify.manifest.json")
line, err := e.Out.ReadString('\n')
require.NoError(t, err)
line = strings.TrimSpace(strings.TrimPrefix(line, "Contract: "))
h, err := util.Uint160DecodeStringLE(line)
require.NoError(t, err)
e.checkTxPersisted(t)
tmpDir := os.TempDir()
walletPath := path.Join(tmpDir, "wallet.json")
e.Run(t, "neo-go", "wallet", "init", "--wallet", walletPath)
defer os.Remove(walletPath)
priv, err := keys.NewPrivateKey()
require.NoError(t, err)
e.In.WriteString("acc\rpass\rpass\r")
e.Run(t, "neo-go", "wallet", "import-deployed",
"--unittest", "--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", walletPath, "--wif", priv.WIF(),
"--contract", h.StringLE())
w, err := wallet.NewWalletFromFile(walletPath)
defer w.Close()
require.NoError(t, err)
require.Equal(t, 1, len(w.Accounts))
contractAddr := w.Accounts[0].Address
require.Equal(t, address.Uint160ToString(h), contractAddr)
require.True(t, w.Accounts[0].Contract.Deployed)
t.Run("Sign", func(t *testing.T) {
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "nep5", "multitransfer",
"--unittest", "--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--from", validatorAddr,
"neo:"+contractAddr+":10",
"gas:"+contractAddr+":10")
e.checkTxPersisted(t)
privTo, err := keys.NewPrivateKey()
require.NoError(t, err)
e.In.WriteString("pass\r")
e.Run(t, "neo-go", "wallet", "nep5", "transfer",
"--unittest", "--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", walletPath, "--from", contractAddr,
"--to", privTo.Address(), "--token", "neo", "--amount", "1")
e.checkTxPersisted(t)
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)
})
}

View file

@ -98,6 +98,10 @@ func (a *Account) SignTx(t *transaction.Transaction) error {
if a.privateKey == nil { if a.privateKey == nil {
return errors.New("account is not unlocked") return errors.New("account is not unlocked")
} }
if len(a.Contract.Parameters) == 0 {
t.Scripts = append(t.Scripts, transaction.Witness{})
return nil
}
data := t.GetSignedPart() data := t.GetSignedPart()
if data == nil { if data == nil {
return errors.New("failed to get transaction's signed part") return errors.New("failed to get transaction's signed part")