core: fix contract-based verification script hash

When using contract-based verification it's important to load contract's hash
along with the script, otherwise it won't be valid.

Simplify things along the way.
This commit is contained in:
Roman Khimov 2020-11-26 22:45:51 +03:00
parent 0c7e727859
commit 49f6b33eae

View file

@ -1601,18 +1601,15 @@ var (
// initVerificationVM initializes VM for witness check. // initVerificationVM initializes VM for witness check.
func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160, witness *transaction.Witness) error { func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160, witness *transaction.Witness) error {
var offset int v := ic.VM
var isNative bool if len(witness.VerificationScript) != 0 {
var initMD *manifest.Method
verification := witness.VerificationScript
flags := smartcontract.NoneFlag
if len(verification) != 0 {
if witness.ScriptHash() != hash { if witness.ScriptHash() != hash {
return ErrWitnessHashMismatch return ErrWitnessHashMismatch
} }
if bc.contracts.ByHash(hash) != nil { if bc.contracts.ByHash(hash) != nil {
return ErrNativeContractWitness return ErrNativeContractWitness
} }
v.LoadScriptWithFlags(witness.VerificationScript, smartcontract.NoneFlag)
} else { } else {
cs, err := ic.DAO.GetContractState(hash) cs, err := ic.DAO.GetContractState(hash)
if err != nil { if err != nil {
@ -1622,26 +1619,21 @@ func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160,
if md == nil { if md == nil {
return ErrInvalidVerificationContract return ErrInvalidVerificationContract
} }
verification = cs.Script initMD := cs.Manifest.ABI.GetMethod(manifest.MethodInit)
offset = md.Offset v.LoadScriptWithHash(cs.Script, hash, smartcontract.AllowStates)
initMD = cs.Manifest.ABI.GetMethod(manifest.MethodInit) v.Jump(v.Context(), md.Offset)
isNative = cs.ID < 0
flags = smartcontract.AllowStates
}
v := ic.VM if cs.ID < 0 {
v.LoadScriptWithFlags(verification, flags) w := io.NewBufBinWriter()
v.Jump(v.Context(), offset) emit.Opcodes(w.BinWriter, opcode.DEPTH, opcode.PACK)
if isNative { emit.String(w.BinWriter, manifest.MethodVerify)
w := io.NewBufBinWriter() if w.Err != nil {
emit.Opcodes(w.BinWriter, opcode.DEPTH, opcode.PACK) return w.Err
emit.String(w.BinWriter, manifest.MethodVerify) }
if w.Err != nil { v.LoadScript(w.Bytes())
return w.Err } else if initMD != nil {
v.Call(v.Context(), initMD.Offset)
} }
v.LoadScript(w.Bytes())
} else if initMD != nil {
v.Call(v.Context(), initMD.Offset)
} }
v.LoadScript(witness.InvocationScript) v.LoadScript(witness.InvocationScript)
return nil return nil