test_contract.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. from web3 import Web3
  2. import json
  3. # Monad 测试网 RPC URL
  4. rpc_url = "https://testnet-rpc.monad.xyz"
  5. # 连接到 Monad 测试网
  6. w3 = Web3(Web3.HTTPProvider(rpc_url))
  7. # 检查是否成功连接
  8. if not w3.is_connected():
  9. raise Exception("无法连接到 Monad 测试网")
  10. # 合约地址和 ABI(仅保留 transfer 和 decimals)
  11. contract_address = w3.to_checksum_address("0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701")
  12. abi = json.loads('''[
  13. {"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},
  14. {"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}
  15. ]''')
  16. # 初始化合约
  17. contract = w3.eth.contract(address=contract_address, abi=abi)
  18. # 你的钱包私钥和地址
  19. private_key = "b898cf63a5ec89105ba755ef3b7533c25ea9130ab50fb0db14779fb6efd4f9c6" # 替换为你的私钥
  20. account = w3.eth.account.from_key(private_key)
  21. wallet_address = account.address
  22. # 辅助函数:签名并发送交易
  23. def send_transaction(tx):
  24. """
  25. 签名并发送交易
  26. 参数:
  27. tx: 交易字典
  28. 返回:
  29. 交易回执
  30. """
  31. try:
  32. tx['from'] = wallet_address
  33. tx['nonce'] = w3.eth.get_transaction_count(wallet_address)
  34. tx['gas'] = 100000 # Gas 限额,适用于简单的 transfer
  35. tx['gasPrice'] = w3.eth.gas_price
  36. signed_tx = w3.eth.account.sign_transaction(tx, private_key)
  37. tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction)
  38. return w3.eth.wait_for_transaction_receipt(tx_hash)
  39. except Exception as e:
  40. raise Exception(f"发送交易失败: {str(e)}")
  41. # 转账代币
  42. def transfer(recipient, amount):
  43. """
  44. 转账代币给指定地址
  45. 参数:
  46. recipient: 接收者地址
  47. amount: 转账的代币数量(以代币单位为准,例如 10 表示 10 个代币)
  48. """
  49. try:
  50. # 验证接收者地址
  51. if not w3.is_address(recipient):
  52. raise ValueError("接收者地址无效")
  53. recipient = w3.to_checksum_address(recipient)
  54. # 获取小数位并转换金额
  55. decimals = contract.functions.decimals().call()
  56. if not isinstance(amount, (int, float)) or amount < 0:
  57. raise ValueError("转账金额必须是非负数")
  58. amount_wei = int(amount * 10**decimals) # 转换为最小单位
  59. # 构建交易
  60. tx = contract.functions.transfer(recipient, amount_wei).build_transaction({
  61. 'chainId': w3.eth.chain_id,
  62. 'gas': 100000, # 显式指定 Gas 限额
  63. 'gasPrice': w3.eth.gas_price,
  64. 'nonce': w3.eth.get_transaction_count(wallet_address),
  65. })
  66. # 发送交易
  67. receipt = send_transaction(tx)
  68. print(f"转账成功,交易哈希: {receipt.transactionHash.hex()}")
  69. except Exception as e:
  70. print(f"转账失败: {str(e)}")
  71. # 示例用法
  72. if __name__ == "__main__":
  73. # 转账 10 个代币给指定地址
  74. recipient_address = "0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701" # 0x904d6CEf48D78448E332B90f66e23a5aAedC1A47
  75. transfer(recipient_address, 0.000000005231854) # 修改此处的 10 为你想要转账的代币数量