wallet: provide (*Account).SignHashable API
Make PrivateKey() less used and less useful.
This commit is contained in:
parent
e569edc841
commit
e164625a7f
10 changed files with 24 additions and 16 deletions
|
@ -17,10 +17,8 @@ import (
|
||||||
func InitAndSave(net netmode.Magic, tx *transaction.Transaction, acc *wallet.Account, filename string) error {
|
func InitAndSave(net netmode.Magic, tx *transaction.Transaction, acc *wallet.Account, filename string) error {
|
||||||
scCtx := context.NewParameterContext("Neo.Network.P2P.Payloads.Transaction", net, tx)
|
scCtx := context.NewParameterContext("Neo.Network.P2P.Payloads.Transaction", net, tx)
|
||||||
if acc != nil && acc.CanSign() {
|
if acc != nil && acc.CanSign() {
|
||||||
priv := acc.PrivateKey()
|
sign := acc.SignHashable(net, tx)
|
||||||
pub := priv.PublicKey()
|
if err := scCtx.AddSignature(acc.ScriptHash(), acc.Contract, acc.PublicKey(), sign); err != nil {
|
||||||
sign := priv.SignHashable(uint32(net), tx)
|
|
||||||
if err := scCtx.AddSignature(acc.ScriptHash(), acc.Contract, pub, sign); err != nil {
|
|
||||||
return fmt.Errorf("can't add signature: %w", err)
|
return fmt.Errorf("can't add signature: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,7 @@ func signStoredTransaction(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if acc.CanSign() {
|
if acc.CanSign() {
|
||||||
priv := acc.PrivateKey()
|
sign := acc.SignHashable(pc.Network, pc.Verifiable)
|
||||||
sign := priv.SignHashable(uint32(pc.Network), pc.Verifiable)
|
|
||||||
if err := pc.AddSignature(ch, acc.Contract, acc.PublicKey(), sign); err != nil {
|
if err := pc.AddSignature(ch, acc.Contract, acc.PublicKey(), sign); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ func (s *signer) ScriptHash() util.Uint160 {
|
||||||
// SignHashable implements Signer interface.
|
// SignHashable implements Signer interface.
|
||||||
func (s *signer) SignHashable(magic uint32, item hash.Hashable) []byte {
|
func (s *signer) SignHashable(magic uint32, item hash.Hashable) []byte {
|
||||||
return append([]byte{byte(opcode.PUSHDATA1), 64},
|
return append([]byte{byte(opcode.PUSHDATA1), 64},
|
||||||
(*wallet.Account)(s).PrivateKey().SignHashable(magic, item)...)
|
(*wallet.Account)(s).SignHashable(netmode.Magic(magic), item)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignTx implements Signer interface.
|
// SignTx implements Signer interface.
|
||||||
|
@ -130,7 +130,7 @@ func (m multiSigner) Script() []byte {
|
||||||
func (m multiSigner) SignHashable(magic uint32, item hash.Hashable) []byte {
|
func (m multiSigner) SignHashable(magic uint32, item hash.Hashable) []byte {
|
||||||
var script []byte
|
var script []byte
|
||||||
for i := 0; i < m.m; i++ {
|
for i := 0; i < m.m; i++ {
|
||||||
sign := m.accounts[i].PrivateKey().SignHashable(magic, item)
|
sign := m.accounts[i].SignHashable(netmode.Magic(magic), item)
|
||||||
script = append(script, byte(opcode.PUSHDATA1), 64)
|
script = append(script, byte(opcode.PUSHDATA1), 64)
|
||||||
script = append(script, sign...)
|
script = append(script, sign...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,7 +300,7 @@ func (a *Actor) SendRequestExactly(mainTx *transaction.Transaction, fbTx *transa
|
||||||
FallbackTransaction: fbTx,
|
FallbackTransaction: fbTx,
|
||||||
}
|
}
|
||||||
req.Witness = transaction.Witness{
|
req.Witness = transaction.Witness{
|
||||||
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, a.sender.PrivateKey().SignHashable(uint32(a.GetNetwork()), req)...),
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, a.sender.SignHashable(a.GetNetwork(), req)...),
|
||||||
VerificationScript: a.sender.GetVerificationScript(),
|
VerificationScript: a.sender.GetVerificationScript(),
|
||||||
}
|
}
|
||||||
actualHash, err := a.rpc.SubmitP2PNotaryRequest(req)
|
actualHash, err := a.rpc.SubmitP2PNotaryRequest(req)
|
||||||
|
|
|
@ -938,7 +938,7 @@ func (c *Client) SignAndPushP2PNotaryRequest(mainTx *transaction.Transaction, fa
|
||||||
FallbackTransaction: fallbackTx,
|
FallbackTransaction: fallbackTx,
|
||||||
}
|
}
|
||||||
req.Witness = transaction.Witness{
|
req.Witness = transaction.Witness{
|
||||||
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.PrivateKey().SignHashable(uint32(m), req)...),
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.SignHashable(m, req)...),
|
||||||
VerificationScript: acc.GetVerificationScript(),
|
VerificationScript: acc.GetVerificationScript(),
|
||||||
}
|
}
|
||||||
actualHash, err := c.SubmitP2PNotaryRequest(req)
|
actualHash, err := c.SubmitP2PNotaryRequest(req)
|
||||||
|
|
|
@ -391,7 +391,7 @@ func (n *Notary) PostPersist() {
|
||||||
// finalize adds missing Notary witnesses to the transaction (main or fallback) and pushes it to the network.
|
// finalize adds missing Notary witnesses to the transaction (main or fallback) and pushes it to the network.
|
||||||
func (n *Notary) finalize(acc *wallet.Account, tx *transaction.Transaction, h util.Uint256) error {
|
func (n *Notary) finalize(acc *wallet.Account, tx *transaction.Transaction, h util.Uint256) error {
|
||||||
notaryWitness := transaction.Witness{
|
notaryWitness := transaction.Witness{
|
||||||
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.PrivateKey().SignHashable(uint32(n.Network), tx)...),
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, acc.SignHashable(n.Network, tx)...),
|
||||||
VerificationScript: []byte{},
|
VerificationScript: []byte{},
|
||||||
}
|
}
|
||||||
for i, signer := range tx.Signers {
|
for i, signer := range tx.Signers {
|
||||||
|
|
|
@ -103,7 +103,7 @@ func (s *service) sendValidatedRoot(r *state.MPTRoot, acc *wallet.Account) {
|
||||||
VerificationScript: acc.GetVerificationScript(),
|
VerificationScript: acc.GetVerificationScript(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
sig := acc.PrivateKey().SignHashable(uint32(s.Network), ep)
|
sig := acc.SignHashable(s.Network, ep)
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
emit.Bytes(buf.BinWriter, sig)
|
emit.Bytes(buf.BinWriter, sig)
|
||||||
ep.Witness.InvocationScript = buf.Bytes()
|
ep.Witness.InvocationScript = buf.Bytes()
|
||||||
|
|
|
@ -86,7 +86,7 @@ func (s *service) signAndSend(r *state.MPTRoot) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sig := acc.PrivateKey().SignHashable(uint32(s.Network), r)
|
sig := acc.SignHashable(s.Network, r)
|
||||||
incRoot := s.getIncompleteRoot(r.Index, myIndex)
|
incRoot := s.getIncompleteRoot(r.Index, myIndex)
|
||||||
incRoot.Lock()
|
incRoot.Lock()
|
||||||
defer incRoot.Unlock()
|
defer incRoot.Unlock()
|
||||||
|
@ -116,7 +116,7 @@ func (s *service) signAndSend(r *state.MPTRoot) error {
|
||||||
VerificationScript: acc.GetVerificationScript(),
|
VerificationScript: acc.GetVerificationScript(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
sig = acc.PrivateKey().SignHashable(uint32(s.Network), e)
|
sig = acc.SignHashable(s.Network, e)
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
emit.Bytes(buf.BinWriter, sig)
|
emit.Bytes(buf.BinWriter, sig)
|
||||||
e.Witness.InvocationScript = buf.Bytes()
|
e.Witness.InvocationScript = buf.Bytes()
|
||||||
|
|
|
@ -126,6 +126,15 @@ func (a *Account) SignTx(net netmode.Magic, t *transaction.Transaction) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SignHashable signs the given Hashable item and returns the signature. If this
|
||||||
|
// account can't sign (CanSign() returns false) nil is returned.
|
||||||
|
func (a *Account) SignHashable(net netmode.Magic, item hash.Hashable) []byte {
|
||||||
|
if !a.CanSign() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return a.privateKey.SignHashable(uint32(net), item)
|
||||||
|
}
|
||||||
|
|
||||||
// CanSign returns true when account is not locked and has a decrypted private
|
// CanSign returns true when account is not locked and has a decrypted private
|
||||||
// key inside, so it's ready to create real signatures.
|
// key inside, so it's ready to create real signatures.
|
||||||
func (a *Account) CanSign() bool {
|
func (a *Account) CanSign() bool {
|
||||||
|
|
|
@ -142,6 +142,7 @@ func TestContractSignTx(t *testing.T) {
|
||||||
require.False(t, acc2.CanSign())
|
require.False(t, acc2.CanSign())
|
||||||
require.Error(t, acc2.SignTx(0, tx)) // Locked account.
|
require.Error(t, acc2.SignTx(0, tx)) // Locked account.
|
||||||
require.Nil(t, acc2.PublicKey()) // Locked account.
|
require.Nil(t, acc2.PublicKey()) // Locked account.
|
||||||
|
require.Nil(t, acc2.SignHashable(0, tx)) // Locked account.
|
||||||
|
|
||||||
acc2.Locked = false
|
acc2.Locked = false
|
||||||
acc2.Close()
|
acc2.Close()
|
||||||
|
@ -155,6 +156,7 @@ func TestContractSignTx(t *testing.T) {
|
||||||
})
|
})
|
||||||
require.NoError(t, acc.SignTx(0, tx)) // Add invocation script for existing witness.
|
require.NoError(t, acc.SignTx(0, tx)) // Add invocation script for existing witness.
|
||||||
require.Equal(t, 66, len(tx.Scripts[1].InvocationScript))
|
require.Equal(t, 66, len(tx.Scripts[1].InvocationScript))
|
||||||
|
require.NotNil(t, acc.SignHashable(0, tx)) // Works via Hashable too.
|
||||||
|
|
||||||
require.NoError(t, multiAcc.SignTx(0, tx))
|
require.NoError(t, multiAcc.SignTx(0, tx))
|
||||||
require.Equal(t, 3, len(tx.Scripts))
|
require.Equal(t, 3, len(tx.Scripts))
|
||||||
|
|
Loading…
Reference in a new issue