使用eosjs部署EOS智能合约时如何解决'missing setcode.vmtype'错误
解决EOSJS部署合约时的
missing setcode.vmtype (type=uint8)错误 我看到你在使用eosjs部署EOS智能合约时遇到了这个错误,这是因为调用eosio::setcode动作时缺少了必填参数,另外你的代码还有重复定义和递归调用的问题,我来一步步帮你修复:
错误原因分析
setcode动作的data对象必须包含四个必填字段:
account: 合约账户名vmtype: 虚拟机类型,固定为0(对应EOS主网默认使用的WABT虚拟机)vmversion: 虚拟机版本,固定为0code: WASM文件的十六进制字符串
你的代码里只传了account和code,缺少vmtype和vmversion,所以触发了序列化错误。
额外代码问题修复
你的代码还有两个明显的冗余问题:
- 在
deployContract函数内部重复定义了所有依赖(比如fs、eosjs模块),完全没必要,这些应该放在全局作用域 - 函数内部递归调用了
deployContract(),会导致无限递归,直接删除这行即可
修正后的完整代码
const wasmFilePath = './hello.wasm' const abiFilePath = './hello.abi' const fs = require('fs') const { Api, JsonRpc, Serialize } = require('eosjs'); const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig'); // development only const fetch = require('node-fetch'); //node only const { TextDecoder, TextEncoder } = require('util'); //node only // 替换成你的合约账户名 const user_name = 'yourcontractacc'; let privateKey1 = '5J***********' const privateKeys = [privateKey1]; const signatureProvider = new JsSignatureProvider(privateKeys); const rpc = new JsonRpc('https://jungle2.cryptolions.io:443', { fetch }); //required to read blockchain state const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }); // 读取并处理WASM和ABI文件 const wasmHexString = fs.readFileSync(wasmFilePath).toString('hex') const buffer = new Serialize.SerialBuffer({ textEncoder: api.textEncoder, textDecoder: api.textDecoder, }) let abiJSON = JSON.parse(fs.readFileSync(abiFilePath, 'utf8')) const abiDefinitions = api.abiTypes.get('abi_def') abiJSON = abiDefinitions.fields.reduce( (acc, { name: fieldName }) => Object.assign(acc, { [fieldName]: acc[fieldName] || [] }), abiJSON ) abiDefinitions.serialize(buffer, abiJSON) const serializedAbiHexString = Buffer.from(buffer.asUint8Array()).toString('hex') // 部署合约函数 async function deployContract(){ try{ await api.transact( { actions: [ { account: 'eosio', name: 'setcode', authorization: [ { actor: user_name, permission: 'active', }, ], data: { account: user_name, vmtype: 0, // 添加必填字段 vmversion: 0, // 添加必填字段 code: wasmHexString, }, }, { account: 'eosio', name: 'setabi', authorization: [ { actor: user_name, permission: 'active', }, ], data: { account: user_name, abi: serializedAbiHexString, }, }, ], }, { blocksBehind: 3, expireSeconds: 30, } ) console.log("合约部署成功!"); } catch(e){ console.error("部署失败:", e); } } // 执行部署 deployContract();
关键修改说明
- 给
setcode的data对象添加了vmtype: 0和vmversion: 0两个必填字段 - 将所有依赖定义移到全局作用域,避免重复加载模块
- 删除了函数内部的递归调用逻辑
- 新增了
user_name变量定义(记得替换成你自己的合约账户名) - 增加了成功日志输出,方便快速确认部署结果
现在运行修正后的脚本,应该就能正常完成合约部署了。
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

