Solidity

外部賬戶可以創建一個可以做任何外部賬戶告訴它做的任何事情的合約嗎?

  • May 21, 2016

外部賬戶是否可以創建一個合約來執行外部賬戶要求它做的任何事情,包括呼叫任意合約和發送乙太幣?

也就是說,合約沒有定義具體的方法,但可以做任何外部賬戶可以做的事情,所以它可能有一個通用方法,只有所有者地址可以使用,它接收所有者希望合約做的作為參數(呼叫另一個合約,發送乙太幣等)。

是否可以在 Solidity 中實現這樣的合約?

Vitalik 提供了一個範例(在 Serpent 中),現在應該可以移植到 Solidity。

# We assume that data takes the following schema:
# bytes 0-31: v (ECDSA sig)
# bytes 32-63: r (ECDSA sig)
# bytes 64-95: s (ECDSA sig)
# bytes 96-127: sequence number (formerly called "nonce")
# bytes 128-159: gasprice
# bytes 172-191: to
# bytes 192-223: value
# bytes 224+: data

# Get the hash for transaction signing
~mstore(0, ~txexecgas())
~calldatacopy(32, 96, ~calldatasize() - 96)
~mstore(0, ~sha3(0, ~calldatasize() - 64))
~calldatacopy(32, 0, 96)
# Call ECRECOVER contract to get the sender
~call(5000, 1, 0, 0, 128, 0, 32)
# Check sender correctness; exception if not
if ~mload(0) != 0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1:
   ~invalid()
# Sequence number operations
with minusone = ~sub(0, 1):
   with curseq = self.storage[minusone]:
       # Check sequence number correctness, exception if not
       if ~calldataload(96) != curseq:
           ~invalid()
       # Increment sequence number
       self.storage[minusone] = curseq + 1
# Make the sub-call and discard output
with x = ~msize():
   ~call(msg.gas - 50000, ~calldataload(160), ~calldataload(192), 160, ~calldatasize() - 224, x, 1000)
   # Pay for gas
   ~mstore(0, ~calldataload(128))
   ~mstore(32, (~txexecgas() - msg.gas + 50000))
   ~call(12000, ETHER, 0, 0, 64, 0, 0)
   ~return(x, ~msize() - x)

該程式碼將作為使用者賬戶的合約程式碼;如果使用者想要發送一筆交易,他們會發送一筆交易(從零地址開始)到這個賬戶,使用指定的編碼對 ECDSA 簽名、序列號、gasprice、目標地址、乙太幣值和實際交易數據進行編碼上面的程式碼。程式碼根據交易氣體限制和提供的數據檢查簽名,然後檢查序列號,如果兩者都正確,則增加序列號,發送所需的消息,然後在最後發送第二條消息進行支付用於gas(注意礦工可以靜態分析賬戶,拒絕處理髮送到最後沒有gas支付碼的賬戶的交易)。

現在不可移植的可見部分(可能是其他部分)~txexecgas()是一個新的操作碼(EIP 101的第 8 點),但由於礦工目前獲得報酬,因此目前不需要它。

參考資料(新舊):

引用自:https://ethereum.stackexchange.com/questions/3847