如何为我的DApp添加NFT拍卖功能并正确实现交易签名流程?
报错原因说明
你遇到的Error: The method 'eth_signTransaction' does not exist / is not available报错,是因为eth_signTransaction这个RPC方法已经被所有主流EVM钱包(比如MetaMask)弃用,该方法存在极高的资产被盗风险,因此钱包服务商均未开放该接口。另外绝对不要在前端要求用户提供私钥完成签名,这属于严重的安全漏洞,会直接导致用户资产失窃。
OpenSea、Foundation类NFT市场的拍卖签名&交易完整逻辑
主流平台均采用链下签名撮合+链上最终结算的模式,全程用户私钥不会离开本地钱包,前端不需要接触私钥,所有签名操作均由用户本地钱包完成,完整流程如下:
- 卖家挂单阶段
- 前端调用钱包注入的
eth_sendTransaction方法,发起NFT授权交易,请求用户授权市场合约可转移对应NFT,用户在钱包弹窗确认后交易上链,授权完成后方可发起挂单。 - 前端构造拍卖规则参数(起拍价、拍卖时长、支付代币类型、最低加价幅度、卖家地址、NFT合约地址+ID等),调用钱包的
eth_signTypedData_v4方法(遵循EIP-712结构化签名标准)请求用户对参数做离线签名,该操作不需要支付Gas,仅作为用户认可拍卖规则的凭证。 - 前端将拍卖参数、用户签名、NFT信息上传到平台后端存储,挂单完成,无需上链,可节省Gas成本。如果是全链上拍卖模式,该步骤直接调用拍卖合约的
createAuction方法发起交易,用户确认后拍卖规则直接上链存储,所有拍卖逻辑由合约自动执行。
- 前端调用钱包注入的
- 买家出价阶段
- 若买家使用ERC20代币出价,需要先调用
eth_sendTransaction发起代币授权交易,授权市场合约可转出对应额度的代币;使用ETH出价则无需授权。 - 前端构造出价参数(出价金额、出价有效期、对应拍卖ID、买家地址等),同样调用
eth_signTypedData_v4请求用户做离线签名,上传到平台后端存储即可,不需要上链。
- 若买家使用ERC20代币出价,需要先调用
- 拍卖成交结算阶段
- 拍卖到期后,平台后端校验最高出价对应的卖家签名、买家签名均合法有效,前端构造结算交易参数,调用
eth_sendTransaction请求交易发起方(可由卖家、买家、平台任意一方发起,取决于合约设计)确认交易,调用市场合约的settleAuction方法。 - 合约内部自动校验双方签名合法性、拍卖状态、出价有效性,校验通过后自动执行:NFT转移给买家、买家出价资金扣除平台手续费后转移给卖家,交易上链完成结算。
- 拍卖到期后,平台后端校验最高出价对应的卖家签名、买家签名均合法有效,前端构造结算交易参数,调用
问题修复方案
所有涉及用户签名的操作,全部通过用户钱包注入的Provider(通常是window.ethereum)调用eth_sendTransaction或者eth_signTypedData_v4方法完成,不要使用web3.js中需要传入私钥的签名相关方法。
内容的提问来源于stack exchange,提问作者Taseen Tanvir
相关产品推荐
相关产品推荐

