使用polkadot.js部署合约报错:contract.tx.new不是函数求协助
问题解决:polkadot.js部署合约报错
contract.tx.new is not a function 错误原因
你误用了ContractPromise的用途:ContractPromise是用来与已部署完成的合约交互的类,它的第三个参数需要传入已部署合约的地址,而非合约的Wasm字节码。直接传入Wasm会导致生成的实例不具备部署合约的tx.new方法,从而触发报错。
正确解决方案
部署合约需要使用BlueprintPromise类(来自@polkadot/api-contract),它专门用于处理合约的实例化(部署)操作。以下是修正后的代码:
import { BlueprintPromise } from '@polkadot/api-contract'; const deployContract = async () => { const contractWasm = contract_file.source.wasm; // 用BlueprintPromise创建合约部署蓝图 const blueprint = new BlueprintPromise(api, abi, contractWasm); const initValue = true; // 估算部署所需gas(可选但推荐,避免gas不足) const { gasRequired, storageDeposit } = await blueprint.query.new( account.address, // 部署账户地址 { storageDepositLimit }, initValue ); // 发起部署交易 const unsub = await blueprint.tx.new({ gasLimit: gasRequired.muln(1.2), // 预留20%的gas余量 storageDepositLimit, value: 0 // 若需向合约转账则设置对应金额,默认0 }, initValue).signAndSend(account, (result) => { if (result.status.isInBlock) { console.log('部署交易已上链'); // 从事件中提取合约地址 const instantiatedEvent = result.events.find(({ event }) => api.events.contracts.Instantiated.is(event) ); if (instantiatedEvent) { const contractAddress = instantiatedEvent.event.data[1].toString(); setContractAddress(contractAddress); console.log('合约部署完成,地址:', contractAddress); } unsub(); // 取消监听 } else if (result.status.isFinalized) { console.log('部署交易已最终确认'); } }); };
关键注意事项
- 确保
account是通过polkadot.js扩展获取的已授权账户对象,具备签名交易的权限。 - 优先通过
blueprint.query.new估算gas和存储押金,避免因参数设置不足导致交易失败。 - 合约部署完成后,需从
Instantiated事件中提取合约地址,而非直接从实例获取(部署前实例无有效地址)。
内容的提问来源于stack exchange,提问作者s.Takahashi
相关产品推荐
相关产品推荐

