2.3GetEntryScriptHash
在智能合约的调用中,有直接调用者就有间接调用者(跨合约调用)。GetEntryScriptHash,它会返回入口(最初)调用者的脚本哈希。我们准备两个智能合约,合约A与合约B,假定合约A来调用合约B的功能函数。
合约B的代码如下:
fromontology.interop.System.ExecutionEngineimportGetExecutingScriptHash,GetCallingScriptHash,GetEntryScriptHash
fromontology.interop.System.RuntimeimportCheckWitness,GetTime,Notify,Serialize,Deserialize
defMain(operation,args):
ifoperation=="invokeB":
returninvokeB()
ifoperation=="avoidToBeInvokedByContract":
returnavoidToBeInvokedByContract()
returnFalse
definvokeB():
#theresultofGetCallingScriptHashandGetEntryScriptHashissame
#iftheyareinvokedbythesamecontract
callerHash=GetCallingScriptHash()
entryHash=GetEntryScriptHash()
Notify([callerHash,entryHash])
return[callerHash,entryHash]
defavoidToBeInvokedByContract():
#thepurposeistopreventhackfromothercontract
callerHash=GetCallingScriptHash()
entryHash=GetEntryScriptHash()
ifcallerHash!=entryHash:
Notify(["Youarenotallowedtoinvokethismethodthroughcontract"])
returnFalse
else:
Notify(["Youcanimplementwhatyouneedtodohere!"])
returnTrue
合约A的代码如下,该合约调用合约B。
fromontology.interop.System.AppimportRegisterAppCall
fromontology.interop.System.ExecutionEngineimportGetExecutingScriptHash,GetCallingScriptHash,GetEntryScriptHash
fromontology.interop.System.RuntimeimportCheckWitness,GetTime,Notify,Serialize,Deserialize
ContractB=RegisterAppCall("0f44f18d37515a917364362ec256c2110a7b1377","operation","args")
defMain(operation,args):
ifoperation=="invokeA":
opt=args[0]
returninvokeA(opt)
ifoperation=="checkHash":
returncheckHash()
returnFalse
definvokeA(opt):
callerHash=GetCallingScriptHash()
entryHash=GetEntryScriptHash()
Notify(["111_invokeA",callerHash,entryHash])
returnContractB(opt,[])
defcheckHash():
Notify(["111_checkHash"])
callerHash=GetCallingScriptHash()
entryHash=GetEntryScriptHash()
Notify([callerHash,entryHash])
returnTrue
如图,首先运行checkHash函数,我们发现在同一个合约的同一个函数中,调用GetCallingScriptHash与GetEntryScriptHashAPI返回值相同,都是"a37ca1f1a3421d36b504769a96c06024a07b2bfa"。这是因为他们既是直接调用者,也是最初调用者(没有跨合约调用),所以两个API返回值相同。但如果跨合约调用呢?