Web3.py

SAI - DAI 符號未正確擷取 Web3.py

  • February 27, 2020

嘗試使用 web3.py擷取交易收據的符號。我得到了 DAI、DAI 和 DAI……而這應該返回 SAI、SAI、DAI。雖然,我檢查了交易日誌下是否提取了正確的 SAI 合約。有人可以告訴我這是我的程式碼中的錯誤還是 web3.py 如何從節點中獲取符號的錯誤?

import json
import urllib.request
from web3 import Web3
import web3

provider = Web3.HTTPProvider('https://mainnet.infura.io/v3/XXXXXXXXXXXXXXXXXXX')
w3 = Web3(provider)
ether_scan_api ='XXXXXXXXXXXXXXXXXXXXXXXX'
tx_hash = '0x52caaf79bf913064a70a6c9d917fd4190cdb099fe79e7d3a9dfe0600e1cfbc81'
receipt=  w3.eth.getTransactionReceipt(tx_hash)
transfer_event = "Transfer(address,address,uint256)"
transfer_event_hashed = w3.keccak(text=transfer_event)
transactions = list()


def get_abi(erc_20_address):
   requrl  = 'https://api.etherscan.io/api?module=contract&action=getabi&address='+erc_20_address+'&apikey='+ ether_scan_api
   while True:
       with urllib.request.urlopen(requrl) as url:
           if url.code != 200:
               raise NotImplementedError('I don\'t know how to handle HTTP code {} :('.format(url.code))
           else:
               result = json.loads(url.read())

               if result['status'] == '1':
                   break
   return  json.loads(result['result'])


for log in receipt.logs:
   if log["topics"][0]==transfer_event_hashed:                
       contract_address = w3.eth.web3.toChecksumAddress(log["address"])                
       token_contract = w3.eth.contract(address=contract_address ,abi=get_abi(contract_address))
       symbol = str(token_contract.functions.symbol().call()[:3])
       print(symbol)

在此處輸入圖像描述

列印收據返回此

AttributeDict({'address': '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359',
'blockHash': HexBytes('0x9e48b35141e53758171239d618a02a9a0e073506b12a5fecca59240c0e032487'),
'blockNumber': 9560511,
'data': '0x00000000000000000000000000000000000000000000000000d529ae9e860000',
'logIndex': 156,
'removed': False,
'topics': [HexBytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'),
 HexBytes('0x00000000000000000000000017b11c26f6cb263864610379a6ebec29da49aa2d'),
 HexBytes('0x000000000000000000000000c73e0383f3aff3215e6f04b0331d58cecf0ab849')],
'transactionHash': HexBytes('0x52caaf79bf913064a70a6c9d917fd4190cdb099fe79e7d3a9dfe0600e1cfbc81'),
'transactionIndex': 111})

很抱歉告訴你,但兩個合約中的符號值都是 DAI。

唯一的區別是“SAI”合約執行bytes32 public symbol,而 DAI 合約執行string public symbol

ERC20 標準規定應該使用後者。

不幸的是,一些代幣供應商未能完全遵守該標準,尤其是在區塊鏈的早期;我猜他們認為這無關緊要。

不幸的是,它確實如此。您正在從 Etherscan 獲取介面,然後使用它來創建合約對象,但大多數應用程序假定介面函式function symbol() public pure returns (string memory),並且當它們呼叫它時,它們要麼得到執行時異常,要麼得到不正確的數據。

無論如何,正如您在此處symbol看到的,“SAI”合約中的函式返回的值是:

0x4441490000000000000000000000000000000000000000000000000000000000

如果將其轉換為 ASCII,則會得到:

  • 0x44 == D
  • 0x41 == A
  • 0x49 == I

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