如果你想知道在EOS上部署了什么版本的智能合约,你需要查看代码哈希。我们将看到如何计算代码和ABI哈希,并编写一个函数,通过比较它们的哈希来查看本地WASM文件是否与正在运行的协议相匹配。
EOS代码的哈希
当通过eosio
setcode
操作设置或更新合约时,检查合约代码是否已经在运行。因此,通过查看setcode
实现,我们可以从WASM文件看到如何计算哈希值。
void apply_eosio_setcode(apply_context& context) {
// some setup code
fc::sha256 code_id; /// default ID == 0
if( act.code.size() > 0 ) {
code_id = fc::sha256::hash( act.code.data(), (uint32_t)act.code.size() );
wasm_interface::validate(context.control, act.code);
}
const auto& account = db.get<account_object,by_name>(act.account);
int64_t code_size = (int64_t)act.code.size();
int64_t old_size = (int64_t)account.code.size() * config::setcode_ram_bytes_multiplier;
int64_t new_size = code_size * config::setcode_ram_bytes_multiplier;
EOS_ASSERT( account.code_version != code_id, set_exact_code, "contract is already running this version of code" );
// ...
}
这只是一个简单的WASM字节表示的sha256哈希值。(第二个参数只是字节数组的长度,哈希函数需要它来知道要对多少字节进行哈希处理。)
在node.js中,我们可以通过哈希一个WASM文件并将其与区块链上代码的哈希值进行比较来轻松实现这一点。
const fs = require(`fs`)
const crypto = require(`crypto`)
const loadFileContents = file => {
if (!fs.existsSync(file)) {
throw new Error(`Code file "${file}" does not exist.`)
}
// no encoding => read as Buffer
return fs.readFileSync(file)
}
const createHash = contents => {
const hash = crypto.createHash(`sha256`)
hash.update(contents)
const digest = hash.digest(`hex`)
return digest
}
// fetch code contract from blockchain
const { code_hash: onChainCodeHash, abi_hash } = await api.rpc.fetch(`/v1/chain