
✨ Dune Analytics零基础极简入门指南
Dune Analytics¹ 号称“平民版 Nansen”、“链上数据分析师神器”,为各路大神所追捧。 然神器在手,奈何找不到适合新手小白的说明书,我等只得望洋兴叹否? 非也! 本文作为一篇入门级的极简教程,适合 Dune 的零基础小白用户,与大家一起掀开 Dune 女神的面纱。何谓 Dune?Dune 作为一款链上数据研究分析的强大工具,经过4轮融资,目前估值已达10亿美元²。 用户通过类SQL的数据库查询语言,从 Dune 缓存的区块链数据仓库中检索、筛选、提取、聚合,形成一个个 Query,再对查询到的数据进行可视化,最终汇总而成一个个 Dashboard 面板。何谓数据仓库?区块链本质上是一个去中心化的账本,所有过往的交易转账、合约调用形成了一条条的交易记录明细,包含交易时间、转入、转出地址、交易金额、调用信息、合约事件、tx_hash 等数据。 Dune 将以上所有数据分门别类进行存储形成数据仓库,供有需要的人通过类SQL语言来调用、查询、分析(可谓功德无量)。何谓 SQL?SQL 即“结构化查询语言”,专用于数据库相关的查询、管理。 在 Dune 中,我们用 SQL...
🔒 Snapshot 投票治理迷你研报
简介本迷你研报,试对 Snapshot 链上投票治理做简要分析,同时列举部分优质项目方,并规划投票权获取方法及参与方式等。 鉴于本人知识面所限,所说内容可能有遗漏、错误等,敬请指正。另本内容仅供内部参考。 简要目录:投票治理简介Snapshot 简介投票项目推荐投票权代币获取推荐配套工具Web3 投票治理简介在民主社会中,投票权被公平赋予每位公民。投票权甚至被认为是现代民主的根本特征。公民行使投票权来进行总统选举这样的国家大事。 在 Web3领域,大量 Web3、DeFi、NFT项目都喜欢追求去中心化的治理模式(不管是实质上还是表面上)。具体的参与方式便是,所有持币(ERC20、ERC721、ERC1155)用户通过签名的方式,为社区提案进行投票,最终根据投票结果来决议。 目前很多 ERC20 代币仅作为治理代币存在,比如 UNI, OP 等。理论上来说,这些代币存在的唯一意义仅包括发起提案、参与投票。然而,持币用户同样有权发起新提案,为代币赋予分红权,进而改变代币经济模型。 持币用户参与投票的行为,一般被视为关心项目发展且积极参与项目治理,为许多项目方所倡导。两种投票治理方式当...

🌍 Charm愿景图:连接加密价值与真实价值
原文:Connecting Crypto Value to Real Value 作者: Tom 译者:gm365Charm 通往可持续未来的路线图过去的16个月里, Charm 为去中心化做市策略(DMMS)开创了一个全新的行业通过为新产品和服务创造流动性市场, DMMS 连接了加密价值与真实价值Alpha Vaults 是第一个使用 DMMS 的产品。它帮 Uniswap V3 在 ETH 和 BTC 上创造了更多的市场流动性Alpha Pro 将是首个使用 DMMS 来帮项目方在 Uniswap V3 上发行代币的产品,它也会是第一个使用 DMMS 来创造新市场的产品本文解释了为什么打造 “Real Value” 非常重要,为什么加密货币最适合于这个目的,以及 Charm 打算帮任何人打造 "Real Value" 的愿景前言创新和创造力是人类进步最强大的决定性因素。数千年以来,它们决定了个人、公司、国家和王朝的兴衰起伏。最伟大的创新,比如电话、蒸汽机、计算机、互联网等,已经在实体经济中(Real Value)创造了大量的价值,并提高了世界各地数十亿人民的生活质量。 金融经...
🐳 Web3 科普 ✨ 尽量言之有物,尽量浅显易懂 🔆 知音如不赏,归卧故山秋。

✨ Dune Analytics零基础极简入门指南
Dune Analytics¹ 号称“平民版 Nansen”、“链上数据分析师神器”,为各路大神所追捧。 然神器在手,奈何找不到适合新手小白的说明书,我等只得望洋兴叹否? 非也! 本文作为一篇入门级的极简教程,适合 Dune 的零基础小白用户,与大家一起掀开 Dune 女神的面纱。何谓 Dune?Dune 作为一款链上数据研究分析的强大工具,经过4轮融资,目前估值已达10亿美元²。 用户通过类SQL的数据库查询语言,从 Dune 缓存的区块链数据仓库中检索、筛选、提取、聚合,形成一个个 Query,再对查询到的数据进行可视化,最终汇总而成一个个 Dashboard 面板。何谓数据仓库?区块链本质上是一个去中心化的账本,所有过往的交易转账、合约调用形成了一条条的交易记录明细,包含交易时间、转入、转出地址、交易金额、调用信息、合约事件、tx_hash 等数据。 Dune 将以上所有数据分门别类进行存储形成数据仓库,供有需要的人通过类SQL语言来调用、查询、分析(可谓功德无量)。何谓 SQL?SQL 即“结构化查询语言”,专用于数据库相关的查询、管理。 在 Dune 中,我们用 SQL...
🔒 Snapshot 投票治理迷你研报
简介本迷你研报,试对 Snapshot 链上投票治理做简要分析,同时列举部分优质项目方,并规划投票权获取方法及参与方式等。 鉴于本人知识面所限,所说内容可能有遗漏、错误等,敬请指正。另本内容仅供内部参考。 简要目录:投票治理简介Snapshot 简介投票项目推荐投票权代币获取推荐配套工具Web3 投票治理简介在民主社会中,投票权被公平赋予每位公民。投票权甚至被认为是现代民主的根本特征。公民行使投票权来进行总统选举这样的国家大事。 在 Web3领域,大量 Web3、DeFi、NFT项目都喜欢追求去中心化的治理模式(不管是实质上还是表面上)。具体的参与方式便是,所有持币(ERC20、ERC721、ERC1155)用户通过签名的方式,为社区提案进行投票,最终根据投票结果来决议。 目前很多 ERC20 代币仅作为治理代币存在,比如 UNI, OP 等。理论上来说,这些代币存在的唯一意义仅包括发起提案、参与投票。然而,持币用户同样有权发起新提案,为代币赋予分红权,进而改变代币经济模型。 持币用户参与投票的行为,一般被视为关心项目发展且积极参与项目治理,为许多项目方所倡导。两种投票治理方式当...

🌍 Charm愿景图:连接加密价值与真实价值
原文:Connecting Crypto Value to Real Value 作者: Tom 译者:gm365Charm 通往可持续未来的路线图过去的16个月里, Charm 为去中心化做市策略(DMMS)开创了一个全新的行业通过为新产品和服务创造流动性市场, DMMS 连接了加密价值与真实价值Alpha Vaults 是第一个使用 DMMS 的产品。它帮 Uniswap V3 在 ETH 和 BTC 上创造了更多的市场流动性Alpha Pro 将是首个使用 DMMS 来帮项目方在 Uniswap V3 上发行代币的产品,它也会是第一个使用 DMMS 来创造新市场的产品本文解释了为什么打造 “Real Value” 非常重要,为什么加密货币最适合于这个目的,以及 Charm 打算帮任何人打造 "Real Value" 的愿景前言创新和创造力是人类进步最强大的决定性因素。数千年以来,它们决定了个人、公司、国家和王朝的兴衰起伏。最伟大的创新,比如电话、蒸汽机、计算机、互联网等,已经在实体经济中(Real Value)创造了大量的价值,并提高了世界各地数十亿人民的生活质量。 金融经...
🐳 Web3 科普 ✨ 尽量言之有物,尽量浅显易懂 🔆 知音如不赏,归卧故山秋。

Subscribe to gm365.eth

Subscribe to gm365.eth
Share Dialog
Share Dialog
>100 subscribers
>100 subscribers


除了 Web3 领域,👨🔬 “科学家”的头衔从没有离普通人这么近过 。
一点点 Python (JavaScrip更好) 基本功、一点点智能合约基础知识、一点点项目投研分析(非必需) = Web3 科学家 。
本文作为一篇零基础教程,献给所有心怀科学家梦想的同学们。
简单来说,通过程序的方式(Python、JavaScript等)进行合约交互、NFT Mint等的用户被统称为“科学家”。
普通用户使用 MetaMask 这样的钱包插件在项目官网进行合约交互或者 Mint NFT,“科学家”使用程序代替人工进行同样的操作 程序代替人工,机器代替人力,效率指数级增加。
蒸汽机的发明将人力从繁重的劳动中解放出来,成功开启了第一次工业革命。
Web3科学家用程序代替人力,解放人力的同时,也获取了诸多优势:
✅ 效率大幅提升(常用于项目交互)
✅ 速度抢先(常用于 NFT Mint)
✅ 自动化程度高
🦾 速度快、效率高、批量化、自动化 = 收益指数级增加
科学界们用程序进行合约交互的两大核心:
▪️ 交互用的程序语言
▪️ 项目合约的交互路径
本文将选用 Python 做交互程序,并选取一两个跨链桥项目做代码演示。本末会有完整的 GitHub 开源代码仓库,供大家借鉴。
Web3 Python 简单易用,第三方库丰富,对新手极其友好。
用 Python 来进行 Web3 项目交互,其桥梁便是 Web3. py,看其名字就透露着野心。
如果你的电脑已经安装好了 Python3,直接用 pip/pip3 即可来安装: 👉 pip install web3
Web3.py 的官方文档:https://web3py.readthedocs.io/en/stable/#
区块链本质上是一个P2P网络共同维护的巨大账本,所有的链上交互信息都是通过某个节点广播到整个 P2P 网络。
然而自建节点成本高昂,对我们大多数人而言,实无必要。我们通过"Infura"这个Web3领域的基础设施门户来接入区块链网络,更加简单便捷。
Infura的使用只需要如下三个步骤:
▪️ 注册账号
▪️ 新建项目
▪️ 获取 PROJECT ID
Infura官网链接: 👉 https://infura.io

Infura目前提供对多条EVM 兼容链的主网、测试网接入节点,只需要切换 network 名称即可。
# get w3 endpoint by network name
def get_w3_by_network(network='mainnet'):
infura_url = f'https://{network}.infura.io/v3/{INFURA_SECRET_KEY}' # 接入 Infura
w3 = Web3(Web3.HTTPProvider(infura_url))
return w3
接入后的 w3 即为我们通向区块链世界的钥匙,不论是查询链上数据,还是进行转账、合约交互,都是通过它来实现。
比如用以下代码来查询 V神 3号钱包的ETH余额,可以得到结果: 29万ETH 🤯
# V神 3号钱包地址
vb = '0x220866b1a2219f40e72f5c628b65d54268ca3a9d'
# 地址格式转换
address = Web3.toChecksumAddress(vb)
# 查询地址 ETH余额
balance = w3.eth.get_balance(address) / 1e18
print(f'V神地址余额: {balance = } ETH')

转账是所有链上交互的灵魂,是一种改变区块链状态的行为。相比较前面的“查询地址余额”,属于“写入”的操作类型。
转账、合约交互等操作,都需要用地址对应的私钥签名交易并广播。
让我们尝试在 Rinkeby 测试网上转账一点ETH测试币
# 转账 ETH
def transfer_eth(w3,from_address,private_key,target_address,amount,gas_price=5,gas_limit=21000,chainId=4):
from_address = Web3.toChecksumAddress(from_address)
target_address = Web3.toChecksumAddress(target_address)
nonce = w3.eth.getTransactionCount(from_address) # 获取 nonce 值
params = {
'from': from_address,
'nonce': nonce,
'to': target_address,
'value': w3.toWei(amount, 'ether'),
'gas': gas_limit,
# 'gasPrice': w3.toWei(gas_price, 'gwei'),
'maxFeePerGas': w3.toWei(gas_price, 'gwei'),
'maxPriorityFeePerGas': w3.toWei(gas_price, 'gwei'),
'chainId': chainId,
}
try:
signed_tx = w3.eth.account.signTransaction(params, private_key=private_key)
txn = w3.eth.sendRawTransaction(signed_tx.rawTransaction)
return {'status': 'succeed', 'txn_hash': w3.toHex(txn), 'task': 'Transfer ETH'}
except Exception as e:
return {'status': 'failed', 'error': e, 'task': 'Transfer ETH'}

❕注意:示例代码中的私钥仅作演示用,注意风险。
👉 代码: https://github.com/gm365/Web3_Tutorial/blob/main/transferETH.py
合约交互比起普通转账,又要复杂了一些。
从合约交互开始,会需要额外几个参数:
▪️ 合约地址
▪️ 合约ABI
▪️ 交互的函数名称及具体参数
一般情况下,我们可以拆解为以下三个步骤来完成:
先在Arbitrum官方跨链桥测试网页面手工交互
接着从交互记录,找到 Etherscan上合约地址
定位到合约 "Write Contract" 中的 "depositEth" 函数,获取函数名称及对应参数

注:本例中其实是定位到 “Write As Proxy”的页面,说明当前合约是一个可升级合约
最终编写的 Python 代码如下:
# bridge eth from rinkeby to arbitrum testnet
def bridge_arbitrum_eth(w3, from_address, private_key, contract_address, amount_in_ether, chainId):
from_address = Web3.toChecksumAddress(from_address)
contract_address = Web3.toChecksumAddress(contract_address)
ABI = '[{"inputs":[{"internalType":"uint256","name":"maxSubmissionCost","type":"uint256"}],"name":"depositEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"}]'
amount_in_wei = w3.toWei(amount_in_ether, 'ether')
maxSubmissionCost = int(amount_in_wei * 0.01) # 定义参数值
nonce = w3.eth.getTransactionCount(from_address)
params = {
'chainId': chainId,
'gas': 250000,
'nonce': nonce,
'from': from_address,
'value': amount_in_wei,
# 'gasPrice': w3.toWei('5', 'gwei'),
'maxFeePerGas': w3.toWei(5, 'gwei'),
'maxPriorityFeePerGas': w3.toWei(5, 'gwei'),
'chainId': chainId,
}
contract = w3.eth.contract(address=contract_address, abi=ABI)
# 调用合约的 depositEth 函数,参数为 maxSubmissionCost
func = contract.functions.depositEth(maxSubmissionCost)
try:
tx = func.buildTransaction(params)
signed_tx = w3.eth.account.sign_transaction(tx, private_key=private_key)
txn = w3.eth.sendRawTransaction(signed_tx.rawTransaction)
return {'status': 'succeed', 'txn_hash': w3.toHex(txn), 'task': 'Bridge ETH'}
except Exception as e:
return {'status': 'failed', 'error': e, 'task': 'Bridge ETH'}
👉 完整参考代码: Arbitrum Bridge
合约的 ABI 即应用程序二进制接口,定义了智能合约各函数调用的参数与方法。
对于开源已验证源码的合约,直接在 etherscan 的合约页面即可查到完整的 ABI 信息
比如 Arbitrum 测试网跨链桥: https://rinkeby.etherscan.io/address/0x578bade599406a8fe3d24fd7f7211c0911f5b29e#code

在你手工交互的 Hash 信息页面的最底部,可以看到 "Input Data" 区域。如果是开源合约则直接显示调用的函数名称及参数信息。
对于未开源合约的调用,可以参考之前的一个 Twitter 🧵
理论上,能通过网站交互的,就一定能通过程序来完成。

相比较于 Arbitrum,zkSync 的难度稍微高了一点。因为后者使用了一个可升级合约,导致无法在 Etherscan 网站找到确切的 ABI 信息 。
不过,通过前一条 🧵 中的方法,最终在网站 chunk-vendor-xxx.js 文件中定位到了完整的 ABI 信息。
✅ 难关攻克
示例代码:
# bridge eth from goerli to zkSync 2.0 testnet
def bridge_zkSync_eth(w3, from_address, private_key, contract_address, amount_in_ether, chainId):
from_address = Web3.toChecksumAddress(from_address)
contract_address = Web3.toChecksumAddress(contract_address)
# Deposit ETH ABI
ABI = '[{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_zkSyncAddress","type":"address"},{"internalType":"enum Operations.QueueType","name":"_queueType","type":"uint8"},{"internalType":"enum Operations.OpTree","name":"_opTree","type":"uint8"}],"name":"depositETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"emergencyFreezeDiamond","outputs":[],"stateMutability":"nonpayable","type":"function"}]'
amount_in_wei = w3.toWei(amount_in_ether, 'ether')
nonce = w3.eth.getTransactionCount(from_address)
# goerli链:无须设置 gas, gas price , chainId, 会自动计算并配置为 EIP 1559 类型
tx_params = {
'value': amount_in_wei,
"nonce": nonce,
# 'gas': 150000,
# 'gasPrice': w3.toWei(2, 'gwei'),
# 'maxFeePerGas': w3.toWei(8, 'gwei'),
# 'maxPriorityFeePerGas': w3.toWei(2, 'gwei'),
# 'chainId': chainId,
}
contract = w3.eth.contract(address=contract_address, abi=ABI)
try:
raw_txn = contract.functions.depositETH(amount_in_wei, from_address, 0, 0).buildTransaction(tx_params)
signed_txn = w3.eth.account.sign_transaction(raw_txn, private_key=private_key)
txn = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
return {'status': 'succeed', 'txn_hash': w3.toHex(txn), 'task': 'zkSync Bridge ETH'}
except Exception as e:
return {'status': 'failed', 'error': e, 'task': 'zkSync Bridge ETH'}

Bungee 跨链桥最近添加了一个 Refuel 模块,可以帮你把一条链的原生代币,跨链并兑换为另一条链的原生代币(用于),功能相当实用。
相比较于之前的任务,这个交互的难度在两颗 🌟
▪️ 合约开源
▪️ 参数只有两枚
唯一需要研究清楚的就只是"destinationChainId"所对应的具体数值(跨链到不同目的地,其定义的 destinationChainId 是不一样的)
具体的实现代码没有给出,留作大家的课堂作业吧。


用程序来交互合约,核心就四个步骤:
▪️ 确定合约地址
▪️ 找到合约ABI
▪️ 研究函数名及参数具体含义
▪️ 写交互代码,广播交易信息
像跨链桥这类合约开源、参数简单、 Gas磨损偏低的, 自然会成为科学家堆积成山的重灾区。
本篇教程内涉及到的 4个任务及对应的完整代码已开源在 GitHub,供大家参考:
建议大家申请好 Infura 的 API Key 之后,先从测试网的几个跨链桥开始尝试。
任何涉及到主网交互的,请务必做好对密钥信息的保密工作,谨防泄漏,以免丢失资产。
👨🔬 交互科学家
测试网简单合约 ➜ 测试网复杂合约 ➜ 主网合约 ➜ 多账号单合约 ➜ 多账号多合约 ➜ 多账号切断关联 ➜ 多账号多合约模拟真实用户行为轨迹 ➜ ( Ξ ) ➜ 躺平
👩🔬 大神科学家
MEV套利 ➜ ( Ξ Ξ Ξ ) ➜ 躺平

所谓 Web3 “科学家”,在大部分语境下,也只不过是用程序代替人工进行合约交互的那群人。
在传统领域,顶多也就称得上是“脚本小子”;但在 Web3 这个蛮荒领域,却被冠以如此高大上的名号,可见行业尚处早期。
然而,随着我们徐徐揭开其神秘面纱,却发现并无太大玄机。学好 Python ,你我皆可登堂入室。
👨🔬 人均科学家的时代即将来临?
任何行业领域内的机会窗口都是稍纵即逝的,越是处于行业早期,越是有较大的先发优势。同时这样的时期也是普通人“逆天改命”最好的时机,是草根阶层实现阶层跨越的绝佳时机。
让我们一起迎接 Web3 的大航海时代 !
附录:
本文原推 🧵:
除了 Web3 领域,👨🔬 “科学家”的头衔从没有离普通人这么近过 。
一点点 Python (JavaScrip更好) 基本功、一点点智能合约基础知识、一点点项目投研分析(非必需) = Web3 科学家 。
本文作为一篇零基础教程,献给所有心怀科学家梦想的同学们。
简单来说,通过程序的方式(Python、JavaScript等)进行合约交互、NFT Mint等的用户被统称为“科学家”。
普通用户使用 MetaMask 这样的钱包插件在项目官网进行合约交互或者 Mint NFT,“科学家”使用程序代替人工进行同样的操作 程序代替人工,机器代替人力,效率指数级增加。
蒸汽机的发明将人力从繁重的劳动中解放出来,成功开启了第一次工业革命。
Web3科学家用程序代替人力,解放人力的同时,也获取了诸多优势:
✅ 效率大幅提升(常用于项目交互)
✅ 速度抢先(常用于 NFT Mint)
✅ 自动化程度高
🦾 速度快、效率高、批量化、自动化 = 收益指数级增加
科学界们用程序进行合约交互的两大核心:
▪️ 交互用的程序语言
▪️ 项目合约的交互路径
本文将选用 Python 做交互程序,并选取一两个跨链桥项目做代码演示。本末会有完整的 GitHub 开源代码仓库,供大家借鉴。
Web3 Python 简单易用,第三方库丰富,对新手极其友好。
用 Python 来进行 Web3 项目交互,其桥梁便是 Web3. py,看其名字就透露着野心。
如果你的电脑已经安装好了 Python3,直接用 pip/pip3 即可来安装: 👉 pip install web3
Web3.py 的官方文档:https://web3py.readthedocs.io/en/stable/#
区块链本质上是一个P2P网络共同维护的巨大账本,所有的链上交互信息都是通过某个节点广播到整个 P2P 网络。
然而自建节点成本高昂,对我们大多数人而言,实无必要。我们通过"Infura"这个Web3领域的基础设施门户来接入区块链网络,更加简单便捷。
Infura的使用只需要如下三个步骤:
▪️ 注册账号
▪️ 新建项目
▪️ 获取 PROJECT ID
Infura官网链接: 👉 https://infura.io

Infura目前提供对多条EVM 兼容链的主网、测试网接入节点,只需要切换 network 名称即可。
# get w3 endpoint by network name
def get_w3_by_network(network='mainnet'):
infura_url = f'https://{network}.infura.io/v3/{INFURA_SECRET_KEY}' # 接入 Infura
w3 = Web3(Web3.HTTPProvider(infura_url))
return w3
接入后的 w3 即为我们通向区块链世界的钥匙,不论是查询链上数据,还是进行转账、合约交互,都是通过它来实现。
比如用以下代码来查询 V神 3号钱包的ETH余额,可以得到结果: 29万ETH 🤯
# V神 3号钱包地址
vb = '0x220866b1a2219f40e72f5c628b65d54268ca3a9d'
# 地址格式转换
address = Web3.toChecksumAddress(vb)
# 查询地址 ETH余额
balance = w3.eth.get_balance(address) / 1e18
print(f'V神地址余额: {balance = } ETH')

转账是所有链上交互的灵魂,是一种改变区块链状态的行为。相比较前面的“查询地址余额”,属于“写入”的操作类型。
转账、合约交互等操作,都需要用地址对应的私钥签名交易并广播。
让我们尝试在 Rinkeby 测试网上转账一点ETH测试币
# 转账 ETH
def transfer_eth(w3,from_address,private_key,target_address,amount,gas_price=5,gas_limit=21000,chainId=4):
from_address = Web3.toChecksumAddress(from_address)
target_address = Web3.toChecksumAddress(target_address)
nonce = w3.eth.getTransactionCount(from_address) # 获取 nonce 值
params = {
'from': from_address,
'nonce': nonce,
'to': target_address,
'value': w3.toWei(amount, 'ether'),
'gas': gas_limit,
# 'gasPrice': w3.toWei(gas_price, 'gwei'),
'maxFeePerGas': w3.toWei(gas_price, 'gwei'),
'maxPriorityFeePerGas': w3.toWei(gas_price, 'gwei'),
'chainId': chainId,
}
try:
signed_tx = w3.eth.account.signTransaction(params, private_key=private_key)
txn = w3.eth.sendRawTransaction(signed_tx.rawTransaction)
return {'status': 'succeed', 'txn_hash': w3.toHex(txn), 'task': 'Transfer ETH'}
except Exception as e:
return {'status': 'failed', 'error': e, 'task': 'Transfer ETH'}

❕注意:示例代码中的私钥仅作演示用,注意风险。
👉 代码: https://github.com/gm365/Web3_Tutorial/blob/main/transferETH.py
合约交互比起普通转账,又要复杂了一些。
从合约交互开始,会需要额外几个参数:
▪️ 合约地址
▪️ 合约ABI
▪️ 交互的函数名称及具体参数
一般情况下,我们可以拆解为以下三个步骤来完成:
先在Arbitrum官方跨链桥测试网页面手工交互
接着从交互记录,找到 Etherscan上合约地址
定位到合约 "Write Contract" 中的 "depositEth" 函数,获取函数名称及对应参数

注:本例中其实是定位到 “Write As Proxy”的页面,说明当前合约是一个可升级合约
最终编写的 Python 代码如下:
# bridge eth from rinkeby to arbitrum testnet
def bridge_arbitrum_eth(w3, from_address, private_key, contract_address, amount_in_ether, chainId):
from_address = Web3.toChecksumAddress(from_address)
contract_address = Web3.toChecksumAddress(contract_address)
ABI = '[{"inputs":[{"internalType":"uint256","name":"maxSubmissionCost","type":"uint256"}],"name":"depositEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"}]'
amount_in_wei = w3.toWei(amount_in_ether, 'ether')
maxSubmissionCost = int(amount_in_wei * 0.01) # 定义参数值
nonce = w3.eth.getTransactionCount(from_address)
params = {
'chainId': chainId,
'gas': 250000,
'nonce': nonce,
'from': from_address,
'value': amount_in_wei,
# 'gasPrice': w3.toWei('5', 'gwei'),
'maxFeePerGas': w3.toWei(5, 'gwei'),
'maxPriorityFeePerGas': w3.toWei(5, 'gwei'),
'chainId': chainId,
}
contract = w3.eth.contract(address=contract_address, abi=ABI)
# 调用合约的 depositEth 函数,参数为 maxSubmissionCost
func = contract.functions.depositEth(maxSubmissionCost)
try:
tx = func.buildTransaction(params)
signed_tx = w3.eth.account.sign_transaction(tx, private_key=private_key)
txn = w3.eth.sendRawTransaction(signed_tx.rawTransaction)
return {'status': 'succeed', 'txn_hash': w3.toHex(txn), 'task': 'Bridge ETH'}
except Exception as e:
return {'status': 'failed', 'error': e, 'task': 'Bridge ETH'}
👉 完整参考代码: Arbitrum Bridge
合约的 ABI 即应用程序二进制接口,定义了智能合约各函数调用的参数与方法。
对于开源已验证源码的合约,直接在 etherscan 的合约页面即可查到完整的 ABI 信息
比如 Arbitrum 测试网跨链桥: https://rinkeby.etherscan.io/address/0x578bade599406a8fe3d24fd7f7211c0911f5b29e#code

在你手工交互的 Hash 信息页面的最底部,可以看到 "Input Data" 区域。如果是开源合约则直接显示调用的函数名称及参数信息。
对于未开源合约的调用,可以参考之前的一个 Twitter 🧵
理论上,能通过网站交互的,就一定能通过程序来完成。

相比较于 Arbitrum,zkSync 的难度稍微高了一点。因为后者使用了一个可升级合约,导致无法在 Etherscan 网站找到确切的 ABI 信息 。
不过,通过前一条 🧵 中的方法,最终在网站 chunk-vendor-xxx.js 文件中定位到了完整的 ABI 信息。
✅ 难关攻克
示例代码:
# bridge eth from goerli to zkSync 2.0 testnet
def bridge_zkSync_eth(w3, from_address, private_key, contract_address, amount_in_ether, chainId):
from_address = Web3.toChecksumAddress(from_address)
contract_address = Web3.toChecksumAddress(contract_address)
# Deposit ETH ABI
ABI = '[{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_zkSyncAddress","type":"address"},{"internalType":"enum Operations.QueueType","name":"_queueType","type":"uint8"},{"internalType":"enum Operations.OpTree","name":"_opTree","type":"uint8"}],"name":"depositETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"emergencyFreezeDiamond","outputs":[],"stateMutability":"nonpayable","type":"function"}]'
amount_in_wei = w3.toWei(amount_in_ether, 'ether')
nonce = w3.eth.getTransactionCount(from_address)
# goerli链:无须设置 gas, gas price , chainId, 会自动计算并配置为 EIP 1559 类型
tx_params = {
'value': amount_in_wei,
"nonce": nonce,
# 'gas': 150000,
# 'gasPrice': w3.toWei(2, 'gwei'),
# 'maxFeePerGas': w3.toWei(8, 'gwei'),
# 'maxPriorityFeePerGas': w3.toWei(2, 'gwei'),
# 'chainId': chainId,
}
contract = w3.eth.contract(address=contract_address, abi=ABI)
try:
raw_txn = contract.functions.depositETH(amount_in_wei, from_address, 0, 0).buildTransaction(tx_params)
signed_txn = w3.eth.account.sign_transaction(raw_txn, private_key=private_key)
txn = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
return {'status': 'succeed', 'txn_hash': w3.toHex(txn), 'task': 'zkSync Bridge ETH'}
except Exception as e:
return {'status': 'failed', 'error': e, 'task': 'zkSync Bridge ETH'}

Bungee 跨链桥最近添加了一个 Refuel 模块,可以帮你把一条链的原生代币,跨链并兑换为另一条链的原生代币(用于),功能相当实用。
相比较于之前的任务,这个交互的难度在两颗 🌟
▪️ 合约开源
▪️ 参数只有两枚
唯一需要研究清楚的就只是"destinationChainId"所对应的具体数值(跨链到不同目的地,其定义的 destinationChainId 是不一样的)
具体的实现代码没有给出,留作大家的课堂作业吧。


用程序来交互合约,核心就四个步骤:
▪️ 确定合约地址
▪️ 找到合约ABI
▪️ 研究函数名及参数具体含义
▪️ 写交互代码,广播交易信息
像跨链桥这类合约开源、参数简单、 Gas磨损偏低的, 自然会成为科学家堆积成山的重灾区。
本篇教程内涉及到的 4个任务及对应的完整代码已开源在 GitHub,供大家参考:
建议大家申请好 Infura 的 API Key 之后,先从测试网的几个跨链桥开始尝试。
任何涉及到主网交互的,请务必做好对密钥信息的保密工作,谨防泄漏,以免丢失资产。
👨🔬 交互科学家
测试网简单合约 ➜ 测试网复杂合约 ➜ 主网合约 ➜ 多账号单合约 ➜ 多账号多合约 ➜ 多账号切断关联 ➜ 多账号多合约模拟真实用户行为轨迹 ➜ ( Ξ ) ➜ 躺平
👩🔬 大神科学家
MEV套利 ➜ ( Ξ Ξ Ξ ) ➜ 躺平

所谓 Web3 “科学家”,在大部分语境下,也只不过是用程序代替人工进行合约交互的那群人。
在传统领域,顶多也就称得上是“脚本小子”;但在 Web3 这个蛮荒领域,却被冠以如此高大上的名号,可见行业尚处早期。
然而,随着我们徐徐揭开其神秘面纱,却发现并无太大玄机。学好 Python ,你我皆可登堂入室。
👨🔬 人均科学家的时代即将来临?
任何行业领域内的机会窗口都是稍纵即逝的,越是处于行业早期,越是有较大的先发优势。同时这样的时期也是普通人“逆天改命”最好的时机,是草根阶层实现阶层跨越的绝佳时机。
让我们一起迎接 Web3 的大航海时代 !
附录:
本文原推 🧵:
No activity yet