Merge pull request #1180 from nspcc-dev/fix-calling-scripthash-check-in-nep5
Add calling scripthash check to native nep5 transfers
This commit is contained in:
commit
acfded7f45
6 changed files with 18 additions and 49 deletions
|
@ -31,6 +31,7 @@ type Context struct {
|
|||
Notifications []state.NotificationEvent
|
||||
Log *zap.Logger
|
||||
Invocations map[util.Uint160]int
|
||||
ScriptGetter vm.ScriptHashGetter
|
||||
}
|
||||
|
||||
// NewContext returns new interop context.
|
||||
|
|
|
@ -14,9 +14,9 @@ import (
|
|||
|
||||
// CheckHashedWitness checks given hash against current list of script hashes
|
||||
// for verifying in the interop context.
|
||||
func CheckHashedWitness(ic *interop.Context, v vm.ScriptHashGetter, hash util.Uint160) (bool, error) {
|
||||
func CheckHashedWitness(ic *interop.Context, hash util.Uint160) (bool, error) {
|
||||
if tx, ok := ic.Container.(*transaction.Transaction); ok {
|
||||
return checkScope(ic.DAO, tx, v, hash)
|
||||
return checkScope(ic.DAO, tx, ic.ScriptGetter, hash)
|
||||
}
|
||||
|
||||
// only for non-Transaction types (Block, etc.)
|
||||
|
@ -79,8 +79,8 @@ func checkScope(d dao.DAO, tx *transaction.Transaction, v vm.ScriptHashGetter, h
|
|||
|
||||
// CheckKeyedWitness checks hash of signature check contract with a given public
|
||||
// key against current list of script hashes for verifying in the interop context.
|
||||
func CheckKeyedWitness(ic *interop.Context, v vm.ScriptHashGetter, key *keys.PublicKey) (bool, error) {
|
||||
return CheckHashedWitness(ic, v, key.GetScriptHash())
|
||||
func CheckKeyedWitness(ic *interop.Context, key *keys.PublicKey) (bool, error) {
|
||||
return CheckHashedWitness(ic, key.GetScriptHash())
|
||||
}
|
||||
|
||||
// CheckWitness checks witnesses.
|
||||
|
@ -96,9 +96,9 @@ func CheckWitness(ic *interop.Context, v *vm.VM) error {
|
|||
if err != nil {
|
||||
return errors.New("parameter given is neither a key nor a hash")
|
||||
}
|
||||
res, err = CheckKeyedWitness(ic, v, key)
|
||||
res, err = CheckKeyedWitness(ic, key)
|
||||
} else {
|
||||
res, err = CheckHashedWitness(ic, v, hash)
|
||||
res, err = CheckHashedWitness(ic, hash)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to check")
|
||||
|
|
|
@ -32,6 +32,7 @@ func SpawnVM(ic *interop.Context) *vm.VM {
|
|||
if ic.Chain != nil {
|
||||
vm.RegisterInteropGetter(ic.Chain.(*Blockchain).contracts.GetNativeInterop(ic))
|
||||
}
|
||||
ic.ScriptGetter = vm
|
||||
return vm
|
||||
}
|
||||
|
||||
|
|
|
@ -254,11 +254,7 @@ func (n *NEO) vote(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
|||
|
||||
// VoteInternal votes from account h for validarors specified in pubs.
|
||||
func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pubs keys.PublicKeys) error {
|
||||
ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{
|
||||
callingScriptHash: util.Uint160{},
|
||||
entryScriptHash: n.Hash,
|
||||
currentScriptHash: n.Hash,
|
||||
}, h)
|
||||
ok, err := runtime.CheckHashedWitness(ic, h)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
|
|
|
@ -175,17 +175,15 @@ func (c *nep5TokenNative) transfer(ic *interop.Context, from, to util.Uint160, a
|
|||
return errors.New("negative amount")
|
||||
}
|
||||
|
||||
ok, err := runtime.CheckHashedWitness(ic, nep5ScriptHash{
|
||||
callingScriptHash: c.Hash,
|
||||
entryScriptHash: c.Hash,
|
||||
currentScriptHash: c.Hash,
|
||||
}, from)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
return errors.New("invalid signature")
|
||||
caller := ic.ScriptGetter.GetCallingScriptHash()
|
||||
if caller.Equals(util.Uint160{}) || !from.Equals(caller) {
|
||||
ok, err := runtime.CheckHashedWitness(ic, from)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
return errors.New("invalid signature")
|
||||
}
|
||||
}
|
||||
|
||||
isEmpty := from.Equals(to) || amount.Sign() == 0
|
||||
inc := amount
|
||||
if isEmpty {
|
||||
|
@ -301,29 +299,6 @@ func toUint160(s stackitem.Item) util.Uint160 {
|
|||
return u
|
||||
}
|
||||
|
||||
// scriptHash is an auxiliary structure which implements ScriptHashGetter
|
||||
// interface over NEP5 native contract and is used for runtime.CheckHashedWitness
|
||||
type nep5ScriptHash struct {
|
||||
callingScriptHash util.Uint160
|
||||
entryScriptHash util.Uint160
|
||||
currentScriptHash util.Uint160
|
||||
}
|
||||
|
||||
// GetCallingScriptHash implements ScriptHashGetter interface
|
||||
func (s nep5ScriptHash) GetCallingScriptHash() util.Uint160 {
|
||||
return s.callingScriptHash
|
||||
}
|
||||
|
||||
// GetEntryScriptHash implements ScriptHashGetter interface
|
||||
func (s nep5ScriptHash) GetEntryScriptHash() util.Uint160 {
|
||||
return s.entryScriptHash
|
||||
}
|
||||
|
||||
// GetCurrentScriptHash implements ScriptHashGetter interface
|
||||
func (s nep5ScriptHash) GetCurrentScriptHash() util.Uint160 {
|
||||
return s.currentScriptHash
|
||||
}
|
||||
|
||||
func getOnPersistWrapper(f func(ic *interop.Context) error) interop.Method {
|
||||
return func(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
|
||||
return stackitem.NewBool(f(ic) == nil)
|
||||
|
|
|
@ -423,11 +423,7 @@ func (p *Policy) checkValidators(ic *interop.Context) (bool, error) {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return runtime.CheckHashedWitness(ic, nep5ScriptHash{
|
||||
callingScriptHash: p.Hash,
|
||||
entryScriptHash: p.Hash,
|
||||
currentScriptHash: p.Hash,
|
||||
}, prevBlock.NextConsensus)
|
||||
return runtime.CheckHashedWitness(ic, prevBlock.NextConsensus)
|
||||
}
|
||||
|
||||
// CheckPolicy checks whether transaction's script hashes for verifying are
|
||||
|
|
Loading…
Reference in a new issue