在 Solana Solidity 程序上调用特定方法
Calling specific methods on a Solana Solidity program
我已经在以太坊区块链上为 运行 构建了一个简单的智能合约,我正试图在 Solana 上复制它的一些行为。在做了一些细微的改动后,我设法用 Solang 编译了针对 Solana 的程序,但我不确定如何调用这些方法;似乎没有大量关于此的文档或示例。比如我的程序是这样写的:
contract Example {
function foo(...) { ... }
function bar(...) { ... }
}
我如何指定对 foo
的调用与对 bar
的调用?此外,我将如何编码这些方法调用的参数?
目前我的方法是使用 @solana/buffer-layout 库将我的参数编码为结构,以 lo.u8('instruction')
开头指定方法调用 (在这个例子中,我假设 0
指的是 foo
而 1
指的是 bar
)。我采用这种方法是基于查看 @solana/spl-token 的源代码(特别是 这个文件 及其依赖项)但是我我不确定它是否适用于使用 Solang 编译的程序,并且缓冲区布局编码也引发了意外错误:
TypeError: Blob.encode requires (length 32) Uint8Array as src
抛出该错误的代码如下:
const method = lo.struct([
lo.u8('instruction'),
lo.seq(
lo.blob(32),
lo.greedy(lo.blob(32).span),
'publicKeys',
),
])
const data = Buffer.alloc(64); // Using method.span here results in an error, as method.span == -1
method.encode(
{
instruction: 0,
publicKeys: [firstPublicKey, secondPublicKey],
},
data,
);
虽然此类型错误看起来很明显,但它与 solana-labs/solana-program-library 存储库中的示例代码不一致。我很确定这个问题与我使用 lo.seq()
有关,但我不确定问题出在哪里。
除了这个类型错误之外,我的方法是否正确,或者我的方法从根本上是错误的?如何使用编码参数调用预期方法?感谢您的帮助。
有一个更好的库供您使用,@solana/solidity
,它有一个 Contract
class 来封装对合约的调用。
例如,在您的情况下,您可以这样做:
const { Connection, LAMPORTS_PER_SOL, Keypair } = require('@solana/web3.js');
const { Contract, Program } = require('@solana/solidity');
const { readFileSync } = require('fs');
const EXAMPLE_ABI = JSON.parse(readFileSync('./example.abi', 'utf8'));
const PROGRAM_SO = readFileSync('./example.so');
(async function () {
console.log('Connecting to your local Solana node ...');
const connection = new Connection('http://localhost:8899', 'confirmed');
const payer = Keypair.generate();
console.log('Airdropping SOL to a new wallet ...');
const signature = await connection.requestAirdrop(payer.publicKey, LAMPORTS_PER_SOL);
await connection.confirmTransaction(signature, 'confirmed');
const program = Keypair.generate();
const storage = Keypair.generate();
const contract = new Contract(connection, program.publicKey, storage.publicKey, EXAMPLE_ABI, payer);
await contract.load(program, PROGRAM_SO);
console.log('Program deployment finished, deploying the example contract ...');
await contract.deploy('example', [true], program, storage);
const res = await contract.functions.foo();
console.log('foo: ' + res.result);
const res2 = await contract.functions.bar();
console.log('bar: ' + res2.result);
})();
例子改编自https://github.com/hyperledger-labs/solang#build-for-solana
有关包裹的更多信息,请访问 https://www.npmjs.com/package/@solana/solidity
我已经在以太坊区块链上为 运行 构建了一个简单的智能合约,我正试图在 Solana 上复制它的一些行为。在做了一些细微的改动后,我设法用 Solang 编译了针对 Solana 的程序,但我不确定如何调用这些方法;似乎没有大量关于此的文档或示例。比如我的程序是这样写的:
contract Example {
function foo(...) { ... }
function bar(...) { ... }
}
我如何指定对 foo
的调用与对 bar
的调用?此外,我将如何编码这些方法调用的参数?
目前我的方法是使用 @solana/buffer-layout 库将我的参数编码为结构,以 lo.u8('instruction')
开头指定方法调用 (在这个例子中,我假设 0
指的是 foo
而 1
指的是 bar
)。我采用这种方法是基于查看 @solana/spl-token 的源代码(特别是 这个文件 及其依赖项)但是我我不确定它是否适用于使用 Solang 编译的程序,并且缓冲区布局编码也引发了意外错误:
TypeError: Blob.encode requires (length 32) Uint8Array as src
抛出该错误的代码如下:
const method = lo.struct([
lo.u8('instruction'),
lo.seq(
lo.blob(32),
lo.greedy(lo.blob(32).span),
'publicKeys',
),
])
const data = Buffer.alloc(64); // Using method.span here results in an error, as method.span == -1
method.encode(
{
instruction: 0,
publicKeys: [firstPublicKey, secondPublicKey],
},
data,
);
虽然此类型错误看起来很明显,但它与 solana-labs/solana-program-library 存储库中的示例代码不一致。我很确定这个问题与我使用 lo.seq()
有关,但我不确定问题出在哪里。
除了这个类型错误之外,我的方法是否正确,或者我的方法从根本上是错误的?如何使用编码参数调用预期方法?感谢您的帮助。
有一个更好的库供您使用,@solana/solidity
,它有一个 Contract
class 来封装对合约的调用。
例如,在您的情况下,您可以这样做:
const { Connection, LAMPORTS_PER_SOL, Keypair } = require('@solana/web3.js');
const { Contract, Program } = require('@solana/solidity');
const { readFileSync } = require('fs');
const EXAMPLE_ABI = JSON.parse(readFileSync('./example.abi', 'utf8'));
const PROGRAM_SO = readFileSync('./example.so');
(async function () {
console.log('Connecting to your local Solana node ...');
const connection = new Connection('http://localhost:8899', 'confirmed');
const payer = Keypair.generate();
console.log('Airdropping SOL to a new wallet ...');
const signature = await connection.requestAirdrop(payer.publicKey, LAMPORTS_PER_SOL);
await connection.confirmTransaction(signature, 'confirmed');
const program = Keypair.generate();
const storage = Keypair.generate();
const contract = new Contract(connection, program.publicKey, storage.publicKey, EXAMPLE_ABI, payer);
await contract.load(program, PROGRAM_SO);
console.log('Program deployment finished, deploying the example contract ...');
await contract.deploy('example', [true], program, storage);
const res = await contract.functions.foo();
console.log('foo: ' + res.result);
const res2 = await contract.functions.bar();
console.log('bar: ' + res2.result);
})();
例子改编自https://github.com/hyperledger-labs/solang#build-for-solana
有关包裹的更多信息,请访问 https://www.npmjs.com/package/@solana/solidity