2018-01-15 18:42:40 +00:00
|
|
|
import
|
|
|
|
../logging, ../constants, ../validation
|
|
|
|
|
|
|
|
type
|
|
|
|
Message* = ref object
|
|
|
|
# A message for VM computation
|
|
|
|
|
|
|
|
# depth = None
|
|
|
|
|
|
|
|
# code = None
|
|
|
|
# codeAddress = None
|
|
|
|
|
|
|
|
# createAddress = None
|
|
|
|
|
|
|
|
# shouldTransferValue = None
|
|
|
|
# isStatic = None
|
|
|
|
|
|
|
|
# logger = logging.getLogger("evm.vm.message.Message")
|
|
|
|
|
|
|
|
gas*: Int256
|
|
|
|
gasPrice*: Int256
|
|
|
|
to*: cstring
|
|
|
|
sender*: cstring
|
|
|
|
value*: Int256
|
2018-01-29 17:40:22 +00:00
|
|
|
data*: seq[byte]
|
2018-01-15 18:42:40 +00:00
|
|
|
code*: cstring
|
|
|
|
internalOrigin: cstring
|
|
|
|
internalCodeAddress: cstring
|
|
|
|
depth*: Int256
|
|
|
|
internalStorageAddress: cstring
|
|
|
|
shouldTransferValue*: bool
|
|
|
|
isStatic*: bool
|
2018-01-16 17:05:20 +00:00
|
|
|
isCreate*: bool
|
|
|
|
|
|
|
|
MessageOptions* = ref object
|
|
|
|
origin*: cstring
|
|
|
|
depth*: Int256
|
|
|
|
createAddress*: cstring
|
|
|
|
codeAddress*: cstring
|
|
|
|
shouldTransferValue*: bool
|
|
|
|
isStatic*: bool
|
2018-01-15 18:42:40 +00:00
|
|
|
|
|
|
|
proc `origin=`*(message: var Message, value: cstring) =
|
|
|
|
message.internalOrigin = value
|
|
|
|
|
|
|
|
proc `codeAddress=`*(message: var Message, value: cstring) =
|
|
|
|
message.internalCodeAddress = value
|
|
|
|
|
|
|
|
proc `storageAddress=`*(message: var Message, value: cstring) =
|
|
|
|
message.internalStorageAddress = value
|
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
proc newMessageOptions*(
|
|
|
|
origin: cstring = nil,
|
2018-01-22 22:23:07 +00:00
|
|
|
depth: Int256 = 0.int256,
|
2018-01-16 17:05:20 +00:00
|
|
|
createAddress: cstring = nil,
|
|
|
|
codeAddress: cstring = nil,
|
|
|
|
shouldTransferValue: bool = true,
|
|
|
|
isStatic: bool = false): MessageOptions =
|
|
|
|
|
|
|
|
result = MessageOptions(
|
|
|
|
origin: origin,
|
|
|
|
depth: depth,
|
|
|
|
createAddress: createAddress,
|
|
|
|
codeAddress: codeAddress,
|
|
|
|
shouldTransferValue: shouldTransferValue,
|
|
|
|
isStatic: isStatic)
|
|
|
|
|
2018-01-15 18:42:40 +00:00
|
|
|
proc newMessage*(
|
|
|
|
gas: Int256,
|
|
|
|
gasPrice: Int256,
|
|
|
|
to: cstring,
|
|
|
|
sender: cstring,
|
|
|
|
value: Int256,
|
2018-01-29 17:40:22 +00:00
|
|
|
data: seq[byte],
|
2018-01-15 18:42:40 +00:00
|
|
|
code: cstring,
|
2018-01-16 17:05:20 +00:00
|
|
|
options: MessageOptions = newMessageOptions()): Message =
|
2018-01-15 18:42:40 +00:00
|
|
|
|
|
|
|
new(result)
|
|
|
|
result.gas = gas
|
|
|
|
result.gasPrice = gasPrice
|
|
|
|
|
|
|
|
if to != CREATE_CONTRACT_ADDRESS:
|
|
|
|
validateCanonicalAddress(to, title="Message.to")
|
|
|
|
result.to = to
|
|
|
|
|
|
|
|
validateCanonicalAddress(sender, title="Message.sender")
|
|
|
|
result.sender = sender
|
|
|
|
|
|
|
|
result.value = value
|
|
|
|
|
|
|
|
result.data = data
|
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
if not options.origin.isNil:
|
|
|
|
validateCanonicalAddress(options.origin, title="Message.origin")
|
|
|
|
result.internalOrigin = options.origin
|
2018-01-15 18:42:40 +00:00
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
validateGte(options.depth, minimum=0, title="Message.depth")
|
|
|
|
result.depth = options.depth
|
2018-01-15 18:42:40 +00:00
|
|
|
|
|
|
|
result.code = code
|
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
if not options.createAddress.isNil:
|
|
|
|
validateCanonicalAddress(options.createAddress, title="Message.storage_address")
|
|
|
|
result.storageAddress = options.createAddress
|
2018-01-15 18:42:40 +00:00
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
if not options.codeAddress.isNil:
|
|
|
|
validateCanonicalAddress(options.codeAddress, title="Message.code_address")
|
|
|
|
result.codeAddress = options.codeAddress
|
2018-01-15 18:42:40 +00:00
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
result.shouldTransferValue = options.shouldTransferValue
|
2018-01-15 18:42:40 +00:00
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
result.isStatic = options.isStatic
|
2018-01-15 18:42:40 +00:00
|
|
|
|
|
|
|
proc origin*(message: Message): cstring =
|
|
|
|
if not message.internalOrigin.isNil:
|
|
|
|
message.internalOrigin
|
|
|
|
else:
|
|
|
|
message.sender
|
|
|
|
|
|
|
|
proc isOrigin*(message: Message): bool =
|
|
|
|
message.sender == message.origin
|
|
|
|
|
|
|
|
proc codeAddress*(message: Message): cstring =
|
|
|
|
if not message.internalCodeAddress.isNil:
|
|
|
|
message.internalCodeAddress
|
|
|
|
else:
|
|
|
|
message.to
|
|
|
|
|
|
|
|
proc `storageAddress`*(message: Message): cstring =
|
|
|
|
if not message.internalStorageAddress.isNil:
|
|
|
|
message.internalStorageAddress
|
|
|
|
else:
|
|
|
|
message.to
|
|
|
|
|
|
|
|
proc isCreate(message: Message): bool =
|
|
|
|
message.to == CREATE_CONTRACT_ADDRESS
|