0

0

在Starknet合约中高效传递长字符串的Python实践指南

心靈之曲

心靈之曲

发布时间:2025-10-29 12:07:26

|

881人浏览过

|

来源于php中文网

原创

在Starknet合约中高效传递长字符串的Python实践指南

本文详细阐述了在starknet合约中通过python传递长字符串的正确方法。鉴于starknet calldata对数组参数的特殊处理机制,直接传递长字符串会导致“input too long for arguments”错误。核心解决方案是将字符串转换为一个由其字符ascii值组成的`u64`数组,并在数组前添加其长度作为第一个元素,以确保合约能够正确解析数据。

理解Starknet Calldata与数组传递机制

在Starknet中,合约调用(Call)的calldata参数是与合约交互的关键。当需要向Starknet合约传递数组类型的数据时,其编码方式与传统Web2开发有所不同。Starknet要求数组的第一个元素必须是数组的长度,随后才是数组的实际元素。如果未能遵循这一约定,尤其是在传递类似长字符串这种被解析为字符数组的数据时,将导致合约无法正确识别参数,从而引发“Input too long for arguments”等错误。

例如,如果希望传递一个整数数组 [8, 13, 21, 34],那么正确的calldata结构应该是 [4, 8, 13, 21, 34],其中 4 代表数组的长度。

长字符串的编码与传递

对于长字符串,Starknet合约通常期望接收的是一个由字符的数值表示(如ASCII或UTF-8编码的整数)构成的数组。这意味着,每个字符都需要被转换为一个 u64 类型的值。

以下是将长字符串转换为Starknet所需calldata格式的Python实现步骤:

立即学习Python免费学习笔记(深入)”;

NeoAgent
NeoAgent

销售易推出的AI‑CRM智能体平台

下载
  1. 字符到整数的转换:遍历字符串中的每个字符,并将其转换为对应的ASCII(或UTF-8)整数值。
  2. 构建长度前缀数组:将转换后的整数列表作为数组元素,并在其前面添加列表的长度。

示例代码:字符串编码函数

def encode_string_to_calldata(long_string: str) -> list[int]:
    """
    将长字符串编码为Starknet合约所需的calldata格式。
    每个字符转换为其ASCII值,并在数组前添加长度。
    """
    # 将字符串中的每个字符转换为其ASCII整数值
    char_values = [ord(char) for char in long_string]
    # 在字符值列表前添加列表的长度
    calldata_array = [len(char_values)] + char_values
    return calldata_array

# 示例使用
long_string_data = "data:,{\"p\":\"stark-20\",\"op\":\"mint\",\"tick\":\"STRK\",\"amt\":\"1000\"}"
encoded_calldata = encode_string_to_calldata(long_string_data)
print(f"原始字符串: {long_string_data}")
print(f"编码后的calldata (部分): {encoded_calldata[:10]}...") # 打印前10个元素和长度
print(f"编码后的calldata长度: {len(encoded_calldata)}")

在Starknet交易中应用编码后的字符串

现在,我们可以将上述编码后的calldata集成到starknet.py的交易构建流程中。

import aiohttp
from starknet_py.net.full_node_client import FullNodeClient
from starknet_py.net.account.account import Account
from starknet_py.net.models import StarknetChainId
from starknet_py.net.signer.models import KeyPair
from starknet_py.net.client_models import Call
from starknet_py.hash.selector import get_selector_from_name

# 假设的配置,请根据实际情况替换
node_url = "YOUR_FULL_NODE_URL" # 例如 "https://alpha-mainnet.starknet.io/rpc/v0.7"
address = 0x0123... # 你的账户地址
private_key = 0x456... # 你的私钥

async def send_transaction_with_long_string():
    async with aiohttp.TCPConnector(ssl=False) as tcpconnector:
        async with aiohttp.ClientSession(connector=tcpconnector, trust_env=True) as session:
            full_node_client = FullNodeClient(node_url=node_url, session=session)
            account = Account(
                client=full_node_client,
                address=address,
                key_pair=KeyPair.from_private_key(key=private_key),
                chain=StarknetChainId.MAINNET,
            )

            # 待传递的长字符串
            long_string_data = "data:,{\"p\":\"stark-20\",\"op\":\"mint\",\"tick\":\"STRK\",\"amt\":\"1000\"}"

            # 使用自定义函数编码字符串
            encoded_calldata_for_string = encode_string_to_calldata(long_string_data)

            # 构建Call对象,注意calldata现在是编码后的数组
            call = Call(
                to_addr=0x07341189e3c96f636a4192cfba8c18deeee33a19c5d0425a26cf96ea42388c4e, # 目标合约地址
                selector=get_selector_from_name("inscribe"), # 目标函数选择器
                calldata=encoded_calldata_for_string # 传递编码后的calldata
            )

            calls = [call]

            # 签署并发送交易
            # 注意:max_fee应根据实际情况设置,0通常用于费用估算
            tx = await account.sign_invoke_transaction(
                calls=calls, max_fee=0 # 初始设置为0以进行费用估算
            )

            # 估算费用
            estimated_fee = await account.client.estimate_fee(tx=tx)
            print(f"估算费用: {estimated_fee.overall_fee}")

            # 重新签署交易,使用估算出的费用(或略高于估算值)
            # tx = await account.sign_invoke_transaction(
            #     calls=calls, max_fee=estimated_fee.overall_fee * 1.1 # 建议略微增加以防波动
            # )
            # resp = await account.client.send_transaction(tx=tx)
            # print(f"交易发送成功,交易哈希: {resp.transaction_hash}")

# 运行异步函数
# import asyncio
# asyncio.run(send_transaction_with_long_string())

通过上述修改,calldata将以Starknet合约期望的数组格式(长度前缀 + 字符ASCII值)进行传递,从而避免“Input too long for arguments”错误。

注意事项与最佳实践

  1. 字符编码:本教程使用ord()函数将字符转换为其ASCII值。对于包含非ASCII字符(如中文)的字符串,需要确保合约端也使用兼容的编码(如UTF-8)进行解析。在Starknet中,通常使用felt(Field Element)来存储数据,felt可以存储252位的整数,足以容纳大多数UTF-8编码的字符。
  2. Calldata大小与Gas费用:calldata的大小直接影响交易的Gas费用。传递非常长的字符串会显著增加交易成本。对于极大的数据,考虑将数据存储在链下(如IPFS),然后只将数据的哈希值传递给合约,以降低链上开销。
  3. 合约端解析:确保Starknet合约中的相应函数能够正确地接收和解析这种带长度前缀的u64数组。例如,一个Cairo合约函数可能定义一个Array类型的参数。
  4. 错误处理:在实际应用中,务必对交易发送和费用估算进行完善的错误处理,并根据实际网络情况调整max_fee。

总结

在Starknet中传递长字符串并非简单地将字符串作为单个参数传入。开发者必须理解Starknet对数组calldata的特殊处理规则,即将字符串编码为一个以长度为前缀的u64整数数组。通过遵循这一模式,并结合适当的Python编码逻辑,可以有效地解决“Input too long for arguments”问题,确保数据能够正确、高效地传递给Starknet合约。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

778

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

685

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

769

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

739

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1445

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

571

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

580

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

751

2023.08.11

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

1

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 21.8万人学习

Django 教程
Django 教程

共28课时 | 3.5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号