You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hedera-sdk-py智能合约部署与查询相关技术问询

Hedera SDK Python版智能合约开发常见问题解答

1. stateful.json是不是编译后的Solidity合约?

不是直接的合约字节码,它是Solidity合约经过编译器编译后生成的标准JSON输出文件,里面包含了合约的十六进制字节码(object字段)、ABI、调试信息等完整编译产物。示例代码里正是提取了stateful_json['object']字段的内容,编码后用来部署到Hedera链上。

2. 怎么把自己的.sol合约转换成这种JSON格式?

可以用Solidity官方编译器solc或者Hardhat、Truffle这类开发框架生成:

方法一:用solc命令行生成

  1. 创建编译配置文件(比如input.json):
{
  "language": "Solidity",
  "sources": {
    "YourContract.sol": {
      "urls": ["YourContract.sol"]
    }
  },
  "settings": {
    "outputSelection": {
      "*": {
        "*": ["*"]
      }
    }
  }
}
  1. 执行编译命令生成标准JSON输出:
solc --standard-json input.json > YourContract.json

生成的YourContract.json就和stateful.json格式一致。

方法二:用Hardhat框架生成

  1. 初始化Hardhat项目后,将你的.sol合约放到contracts目录下。
  2. 执行npx hardhat compile,编译后的JSON文件会存放在artifacts/contracts/目录下,直接即可使用。

3. 部署后如何在合约中存储数据?

核心是通过合约的写函数修改链上状态,结合Hedera SDK的ContractExecuteTransaction触发交易,用ContractCallQuery读取状态,示例代码已给出完整流程:

前提:合约需包含状态变量和读写函数

对应的Solidity合约示例:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract StatefulContract {
    string public message;

    constructor(string memory initialMessage) {
        message = initialMessage;
    }

    function set_message(string memory newMessage) public {
        message = newMessage;
    }

    function get_message() public view returns (string memory) {
        return message;
    }
}

存储数据的具体步骤

  • 修改状态(存数据):用ContractExecuteTransaction调用合约的写函数(比如set_message),这会向Hedera链发送交易、消耗gas,交易确认后链上状态更新。对应示例代码片段:
resp = (ContractExecuteTransaction()
    .setGas(200_000)
    .setContractId(contractId)
    .setFunction("set_message",
                 ContractFunctionParameters().addString("hello from hedera again!")
                )
    .setMaxTransactionFee(Hbar(2))
    .execute(client))
receipt = resp.getReceipt(client)
  • 读取状态(取数据):用ContractCallQuery调用合约的读函数(比如get_message),这是查询操作,不会修改链上状态,仅需支付少量查询费用。对应示例代码片段:
result = (ContractCallQuery()
      .setGas(50000)
      .setContractId(contractId)
      .setFunction("get_message")
      .setQueryPayment(Hbar(1))
      .execute(client))
message = result.getString(0)

完整示例代码

import os
import json

from hedera import (
    Hbar,
    FileCreateTransaction,
    ContractCreateTransaction,
    ContractCallQuery,
    ContractExecuteTransaction,
    ContractFunctionParameters,
)
from get_client import client, OPERATOR_KEY

client.setMaxTransactionFee(Hbar(100))
client.setMaxQueryPayment(Hbar(10))

cur_dir = os.path.abspath(os.path.dirname(__file__))
jsonf = open(os.path.join(cur_dir, "stateful.json"))
stateful_json = json.load(jsonf)
jsonf.close()
byteCode = stateful_json['object'].encode()

tran = FileCreateTransaction()
resp = tran.setKeys(OPERATOR_KEY
      ).setContents(byteCode
      ).execute(client)
fileId = resp.getReceipt(client).fileId
print("contract bytecode file: ", fileId.toString())

tran = ContractCreateTransaction()
resp = tran.setGas(500_000
      ).setBytecodeFileId(fileId
      ).setConstructorParameters(
            ContractFunctionParameters().addString("hello from hedera!")
      ).execute(client)
contractId = resp.getReceipt(client).contractId
print("new contract id: ", contractId.toString())

# 600 < gas fee < 1000
result = (ContractCallQuery()
      .setGas(50000)
      .setContractId(contractId)
      .setFunction("get_message")
      .setQueryPayment(Hbar(1))
      .execute(client))

if result.errorMessage:
    exit("error calling contract: ", result.errorMessage)

message = result.getString(0)
print("contract returned message: ", message)

resp = (ContractExecuteTransaction()
    .setGas(200_000)
    .setContractId(contractId)
    .setFunction("set_message",
                 ContractFunctionParameters().addString("hello from hedera again!")
                )
    .setMaxTransactionFee(Hbar(2))
    .execute(client))

# if this doesn't throw, then we know the contract executed successfully
receipt = resp.getReceipt(client)

# now query contract
result = (ContractCallQuery()
      .setGas(50000)
      .setContractId(contractId)
      .setFunction("get_message")
      .setQueryPayment(Hbar(1))
      .execute(client))

if result.errorMessage:
   exit("error calling contract: ", result.errorMessage)

message = result.getString(0)
print("contract returned message: ", message)

内容的提问来源于stack exchange,提问作者mev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:33:26