solana-labs / solana-solidity.js Goto Github PK
View Code? Open in Web Editor NEWCompile, deploy, and use Solidity contracts on Solana
Home Page: https://solana-labs.github.io/solana-solidity.js
License: Apache License 2.0
Compile, deploy, and use Solidity contracts on Solana
Home Page: https://solana-labs.github.io/solana-solidity.js
License: Apache License 2.0
Did the instruction as described in the README (just added yarn init
and touch yarn.lock
)
OS : Arch Linux / Manjaro
package.json
{
"name": "project",
"packageManager": "[email protected]",
"dependencies": {
"@solana/solidity": "^0.0.18"
}
}
$ node erc20.js
Connecting to your local Solana node ...
Airdropping SOL to a new wallet ...
Deploying the Solang-compiled ERC20 program ...
Program deployment finished, deploying the ERC20 contract ...
Transaction simulation failed: Error processing Instruction 0: custom program error: 0x1
Program 11111111111111111111111111111111 invoke [1]
Transfer: insufficient lamports 33450880, need 228956160
Program 11111111111111111111111111111111 failed: custom program error: 0x1
(node:83032) UnhandledPromiseRejectionWarning: Error: custom program error: 0x1
at parseTransactionError (/home/sum/DEV/SOLANA/solana-solidity.js/project/node_modules/@solana/solidity/lib/logs.js:161:31)
at /home/sum/DEV/SOLANA/solana-solidity.js/project/node_modules/@solana/solidity/lib/logs.js:123:27
at Generator.throw (<anonymous>)
at rejected (/home/sum/DEV/SOLANA/solana-solidity.js/project/node_modules/@solana/solidity/lib/logs.js:6:65)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:83032) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:83032) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
how to deploy to the "https://api.devnet.solana.com"?
I edit "const connection = new Connection('http://localhost:8899', 'confirmed');" to "const connection = new Connection('https://api.devnet.solana.com', 'confirmed');"
Error :
Connecting to your local Solana node ...
Airdropping SOL to a new wallet ...
/Users/leilei/Downloads/solana-solidity.js-master/node_modules/node-fetch/lib/index.js:1461
reject(new FetchError(request to ${request.url} failed, reason: ${err.message}
, 'system', err));
^
FetchError: request to https://api.devnet.solana.com/ failed, reason: Client network socket disconnected before secure TLS connection was established
at ClientRequest. (/Users/leilei/Downloads/solana-solidity.js-master/node_modules/node-fetch/lib/index.js:1461:11)
at ClientRequest.emit (node:events:390:28)
at TLSSocket.socketErrorListener (node:_http_client:447:9)
at TLSSocket.emit (node:events:390:28)
at emitErrorNT (node:internal/streams/destroy:164:8)
at emitErrorCloseNT (node:internal/streams/destroy:129:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
type: 'system',
errno: 'ECONNRESET',
code: 'ECONNRESET'
}
Node.js v17.0.1
I'm not sure how extensive this is, but at lin one case the docs and source are out of sync:deploy()
in the docs still takes a program Signer whereas implementation no longer does.
I tried to use solang to compile an example: flipper.sol and deploy it and test flipper.js but failed:
$ node flipper.js
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
Connecting to your local Solana node ...
Airdropping SOL to a new wallet ...
Program deployment finished, deploying the flipper contract ...
/home/xxx/solidity/node_modules/@solana/solidity/lib/contract.js:106
throw new errors_1.InvalidStorageAccountError();
^InvalidStorageAccountError
at Contract. (/home/xxx/solidity/node_modules/@solana/solidity/lib/contract.js:106:23)
at Generator.next ()
at /home/xxx/solidity/node_modules/@solana/solidity/lib/contract.js:8:71
at new Promise ()
at __awaiter (/home/xxx/solidity/node_modules/@solana/solidity/lib/contract.js:4:12)
at Contract.deploy (/home/xxx/solidity/node_modules/@solana/solidity/lib/contract.js:104:16)
at /home/xxx/solidity/flipper.js:27:20
at runMicrotasks ()
at processTicksAndRejections (node:internal/process/task_queues:96:5)
My env:
Ubuntu20.04.4 on WSL2(windows11),
Solana: 1.10.31
@solana-solidity: 0.0.20
solang: 0.1.12
Any suggestion?
This repo is the holding place for where a new npm package should go, which has not been written yet.
The Solang Solidity Compiler has support for Solana which is maturing. Solang compiles Solidity to BPF contracts, that is, native solana contracts. A npm package is needed to deploy and interact with these contracts. The npm library should have the following:
print()
, and retrieve errorA simple prototype is here https://github.com/seanyoung/uniswap-v2-core/blob/solana/solana/
I'm trying to run the example, but I've faced an issue during running "read" methods of the contract. I tried to deploy simple contract, unfortunately it didn't work as well. Unlike read methods, write methods are working well. Can anybody show a direction to dig?
Environment:
Node: 16 and 18
Solang: v0.1.12
@solana/solidity: v0.0.20
@solana/web3.js: 1.30.2 and 1.43.4
node scripts/deploy-contracts.js
Connecting to your local Solana node ...
Airdropping SOL to a new wallet ...
Deploying the Solang-compiled ERC20 program ...
Program deployment finished, deploying the ERC20 contract ...
Contract deployment finished, invoking some contract functions ...
/Users/user/solana-example/node_modules/@solana/web3.js/lib/index.cjs.js:3073
if (message.header.numRequiredSignatures > 0) {
^
TypeError: Cannot read properties of undefined (reading 'numRequiredSignatures')
at Function.populate (/Users/user/solana-example/node_modules/@solana/web3.js/lib/index.cjs.js:3073:24)
at Connection.simulateTransaction (/Users/user/solana-example/node_modules/@solana/web3.js/lib/index.cjs.js:7278:33)
at /Users/user/solana-example/node_modules/@solana/solidity/lib/logs.js:98:41
at Generator.next (<anonymous>)
at /Users/user/solana-example/node_modules/@solana/solidity/lib/logs.js:8:71
at new Promise (<anonymous>)
at __awaiter (/Users/user/solana-example/node_modules/@solana/solidity/lib/logs.js:4:12)
at simulateTransactionWithLogs (/Users/user/solana-example/node_modules/@solana/solidity/lib/logs.js:97:12)
at Contract.<anonymous> (/Users/user/solana-example/node_modules/@solana/solidity/lib/contract.js:372:64)
at Generator.next (<anonymous>)
Hello Solana Team,
Is it possible to implement smart contract upgradeability similar to Ethereum using Solana-Solidity-JS toolkit.
I implemented a simple contract ERC20Caller.sol, to call write functions of an external ERC20 contract (already deployed). This contract has a function to make an approve call on an external token contract, for which I tried to follow the example in this doc: https://solang.readthedocs.io/_/downloads/en/latest/pdf/
function callERC20ApproveWithSelector(address tokenAddress, address spender, uint256 amount)
public
virtual
returns (bool)
{
ERC20 token = ERC20(tokenAddress);
bytes data = abi.encodeWithSignature("approve(address,uint256)", spender, uint256(amount));
(bool success, bytes rawresult) = address(token).call(data);
assert(success == true);
bool res = abi.decode(rawresult, (bool));
assert(res);
return res;
}
I deployed this by modifying the deployment script in test/examples/utils.ts, and used the Contract interface provided in src/contract.ts.
When I tried to call the above function, using the deployed ERC20 program's id converted to hex as the tokenAddress, I get an error in the logs: Program log: call to account not in transaction
The call was implemented like this:
callerContract = new Contract(
callerContract.connection,
callerContract.program,
callerContract.storage,
callerContract.abi,
callerContract.payer
);
const tokenAccount = publicKeyToHex(tokenProgramId);
const spenderAccount = publicKeyToHex(Keypair.generate().publicKey);
const spendAmount = 9;
await callerContract.callERC20ApproveWithSelector(tokenAccount, spenderAccount, spendAmount);
From what I understand, any account that has its storage changed needs to sign the transaction. In that case I guess I assumed the abstraction in the contract.ts file would be able to handle that.
Let me know if I am missing something, or maybe this functionality is not yet implemented for solang-based programs?
Thanks!
I deployed the erc20 contract in the examples to devnet, and it turns out there are 30 transactions for the program upon deployment.
Was this required to set up the storage for the contract?
Or maybe break the execution logic into several parts?
Any insight would be helpful. Thanks!
https://explorer.solana.com/address/48iyexQULtnRnmUicqG6QJmwcHVeC8ap1xf6Y3Z91TSc?cluster=devnet
Tried to run the example in the readme on devnet and testnet instead of localhost:
Contract deployment finished, invoking some contract functions ...
(node:65474) UnhandledPromiseRejectionWarning: Error: ELF error: Unresolved symbol (sol_set_return_data) at instruction #3690 (ELF file offset 0x7268)
mapping(address => uint256) public transactionCount;
mapping( address => mapping(uint256 => uint256)) public timestamps;
mapping( address => mapping(uint256 => string)) public txTypes;
mapping( address => mapping(uint256 => string)) public txDatas;
function writeTransaction(uint256 _timestamp, string memory _txType, string memory _txData) public returns(uint256){
timestamps[msg.sender][transactionCount[msg.sender]] = _timestamp;
txTypes[msg.sender][transactionCount[msg.sender]] = _txType;
txDatas[msg.sender][transactionCount[msg.sender]] = _txData;
transactionCount[msg.sender] ++;
emit WriteTransaction(msg.sender);
return transactionCount[msg.sender];
}
deploy contract and call "write" function:
const writeTx = await contract.writeTransaction('1000000000000000000', 'TestTx', 'tx data');
!!!!!!!!!!! success
try {
await sleep(60000);
const writeTx1 = await contract.writeTransaction('1000000000000000000', 'TestTx', 'tx data');
} catch (e) {
console.log('e => ', e);
//????????????? failed always
}
Error content:
e => TransactionError: Program failed to complete
at parseTransactionError (/Users/admin/Documents/workspace/tumulus/tumulus/Contracts/Solana/node_modules/@solana/solidity/lib/logs.js:161:31)
at /Users/admin/Documents/workspace/tumulus/tumulus/Contracts/Solana/node_modules/@solana/solidity/lib/logs.js:123:27
at Generator.throw (<anonymous>)
at rejected (/Users/admin/Documents/workspace/tumulus/tumulus/Contracts/Solana/node_modules/@solana/solidity/lib/logs.js:6:65)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
logs: [
'Program 34vt7Bz8tAtVYPUJ6seKZGLgRGWENFNJKgUvreFjo4wt invoke [1]',
'Program 34vt7Bz8tAtVYPUJ6seKZGLgRGWENFNJKgUvreFjo4wt consumed 1489 of 200000 compute units',
**'Program failed to complete: Access violation in input section at address 0x47a70e3ca of size 8 by instruction #11821',**
'Program 34vt7Bz8tAtVYPUJ6seKZGLgRGWENFNJKgUvreFjo4wt failed: Program failed to complete'
],
computeUnitsUsed: 1489
maybe, string type has some problems?
How to get the signature of transaction after executing the contract function written in solidity
const address = publicKeyToHex(payer.publicKey);
^
TypeError: publicKeyToHex is not a function
after airdropping SOL, failed deploying program.
Deploying the Solang-compiled ERC20 program ...
Transaction simulation failed: Attempt to debit an account but found no record of a prior credit.
So I transferred SOL there, and used the generated account again.
in that time:
Deploying the Solang-compiled ERC20 program ...
Transaction simulation failed: Error processing Instruction 0: custom program error: 0x1
Totally, I cannot deploy the program. so I checked issue history. it was same as #18
Hello Solana Devs,
I was trying to setup Solana Solidity JS tool on Ubuntu 20.04 version Linux environment. I am getting the following error while running the 'yarn docker' command. Could you please provide some guidance on the fix for this error.
yarn run v1.22.15
error @solana/[email protected]: The engine "node" is incompatible with this module.
Expected version ">= 14". Got "10.19.0"
error Commands cannot run with an incompatible environment.
How can I call deployed contract with program and storage address ?
when call a solidity function that returns one value like "public view returns (uint256)" is working well.
but returning multi values is not working.
ex: public view returns (uint256, string memory, string memory)
Error detail is like as bellow:
error = new errors_1.TransactionError(log);
^
TransactionError: Access violation in input section at address 0x47a70e3ca of size 8 by instruction #12198
FYI: need more detail description or tests for such returning multi values, returning array and struct usage.
I was trying to deploy the smart contract on solana but while deploying im getting the below error:
Connecting to your local Solana node ...
Airdropping SOL to a new wallet ...
PublicKey {
_bn: <BN: 6a1dddb4942d3ed20116fb801ee73d6ef5e9ec3c805435f96f9cec2a1be5b1c1>
}
(node:30305) UnhandledPromiseRejectionWarning: TypeError: abi.map is not a function
at new Interface (/node_modules/@ethersproject/abi/lib/interface.js:101:60)
at new Contract (node_modules/@solana/solidity/dist/esm/src/contract.js:21:20)
at /ERC20/project/erc20.js:26:22
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:30305) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:30305) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
ERC20.js:
const { Connection, LAMPORTS_PER_SOL, Keypair } = require('@solana/web3.js');
const { Contract, publicKeyToHex } = require('@solana/solidity');
const { readFileSync } = require('fs');
const ERC20_ABI = JSON.parse(readFileSync('./build/ERC20.abi', 'utf8'));
const BUNDLE_SO = readFileSync('./build/bundle.so');
(async function () {
console.log('Connecting to your local Solana node ...');
const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
const payer = Keypair.generate();
while (true) {
console.log('Airdropping SOL to a new wallet ...');
await connection.requestAirdrop(payer.publicKey, 1 * LAMPORTS_PER_SOL);
await new Promise((resolve) => setTimeout(resolve, 1000));
if (await connection.getBalance(payer.publicKey)) break;
}
console.log(payer.publicKey);
const address = '0x' + payer.publicKey.toBuffer().toString('hex');
const program = Keypair.generate();
const storage = Keypair.generate();
const contract = new Contract(
connection,
program.publicKey,
storage.publicKey,
ERC20_ABI,
payer
);
console.log('Deploying the Solang-compiled ERC20 program ...');
await contract.load(program, BUNDLE_SO);
console.log('Program deployment finished, deploying the ERC20 contract ...');
await contract.deploy(
'ERC20',
['Solana', 'SOL', '1000000000000000000'],
program,
storage,
4096 * 8
);
console.log('Contract deployment finished, invoking some contract functions ...');
const symbol = await contract.symbol();
const balance = await contract.balanceOf(address);
console.log(`ERC20 contract for ${symbol} deployed!`);
console.log(`Your wallet at ${address} has a balance of ${balance} tokens.`);
contract.addEventListener(function (event) {
console.log(`${event.name} event emitted!`);
console.log(`${event.args[0]} sent ${event.args[2]} tokens to ${event.args[1]}`);
});
console.log('Sending tokens will emit a "Transfer" event ...');
const recipient = Keypair.generate();
await contract.transfer(publicKeyToHex(recipient.publicKey), '1000000000000000000');
process.exit(0);
})();
I was wondering if there is a good way to calculate the account size before deploying the contract,
as used in
solana-solidity.js/src/contract.ts
Line 260 in 63731bf
if the account would have been serialzied using borsh you could use:
class FlipperAccount {
value = false;
constructor(fields: { initvalue: boolean } | undefined = undefined) {
if (fields) {
this.value = fields.initvalue
}
}
}
// Borsh schema definition for flipper accounts
const FlipperSchema = new Map([
[FlipperAccount, { kind: 'struct', fields: [['value', 'u8 ']] }],
])
const FLIPPER_SIZE = borsh.serialize(
FlipperSchema,
new FlipperAccount(),
).length
But from looking at solang it doesn't look as if the account data is serialized with borsh.
So what would be the equivalent to calculate the account size for the flipper example.
Maybe the account size could be calculated in the Contract class constructor from the .abi and store it.
During Contract,deploy it could be used as a lower bound to calculate rent examption, still the space should be size*2 or larger during deployment so subsequent updates can add more variables to be stored into the account.
Tried to deploy ERC20.sol example
Solang version: v0.1.13
Expected: Successful deploy
Got: TransactionError: invalid program argument
JS Source:
const { Connection, LAMPORTS_PER_SOL, Keypair } = require('@solana/web3.js');
const { Contract } = require('@solana/solidity');
const { readFileSync } = require('fs');
const ERC20_ABI = JSON.parse(readFileSync('./build/ERC20.abi', 'utf8'));
const BUNDLE_SO = readFileSync('./build/bundle.so');
function publicKeyToHex(publicKey) {
return '0x' + publicKey.toBuffer().toString('hex');
}
(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, 10 * LAMPORTS_PER_SOL);
await connection.confirmTransaction(signature, 'confirmed');
const address = publicKeyToHex(payer.publicKey);
const program = Keypair.generate();
const storage = Keypair.generate();
const contract = new Contract(
connection,
program.publicKey,
storage.publicKey,
ERC20_ABI,
payer
);
console.log('Deploying the Solang-compiled ERC20 program ...');
await contract.load(program, BUNDLE_SO);
console.log('Program deployment finished, deploying the ERC20 contract ...');
await contract.deploy(
'ERC20',
['Solana', 'SOL', '1000000000000000000'],
storage,
4096 * 8
);
console.log('Contract deployment finished, invoking some contract functions ...');
const symbol = await contract.symbol();
const balance = await contract.balanceOf(address);
console.log(`ERC20 contract for ${symbol} deployed!`);
console.log(`Your wallet at ${address} has a balance of ${balance} tokens.`);
contract.addEventListener(function (event) {
console.log(`${event.name} event emitted!`);
console.log(`${event.args[0]} sent ${event.args[2]} tokens to ${event.args[1]}`);
});
console.log('Sending tokens will emit a "Transfer" event ...');
const recipient = Keypair.generate();
await contract.transfer(recipient.publicKey.toBytes(), 1000000000000000000);
process.exit(0);
})();
Steps to reproduce
node ERC20.js
-- see source above
Connecting to your local Solana node ...
Airdropping SOL to a new wallet ...
Deploying the Solang-compiled ERC20 program ...
Program deployment finished, deploying the ERC20 contract ...
Transaction simulation failed: Error processing Instruction 1: invalid program argument
Program 11111111111111111111111111111111 invoke [1]
Program 11111111111111111111111111111111 success
Program Hn9KXdnBK6h2A7vZ2YqnnQdqzh8zv92qQsAEBHSHqv7j invoke [1]
Program Hn9KXdnBK6h2A7vZ2YqnnQdqzh8zv92qQsAEBHSHqv7j consumed 550 of 400000 compute units
Program Hn9KXdnBK6h2A7vZ2YqnnQdqzh8zv92qQsAEBHSHqv7j failed: invalid program argument
/Users/xf/Work/mycompany/_research/crypto/solana-apps/solana-solidity.js/node_modules/@solana/solidity/lib/logs.js:162
? new errors_1.TransactionError(failedMatch[2])
^
TransactionError: invalid program argument
at parseTransactionError (/Users/xf/Work/mycompany/_research/crypto/solana-apps/solana-solidity.js/node_modules/@solana/solidity/lib/logs.js:162:15)
at /Users/xf/Work/mycompany/_research/crypto/solana-apps/solana-solidity.js/node_modules/@solana/solidity/lib/logs.js:123:27
at Generator.throw (<anonymous>)
at rejected (/Users/xf/Work/mycompany/_research/crypto/solana-apps/solana-solidity.js/node_modules/@solana/solidity/lib/logs.js:6:65)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
logs: [
'Program 11111111111111111111111111111111 invoke [1]',
'Program 11111111111111111111111111111111 success',
'Program Hn9KXdnBK6h2A7vZ2YqnnQdqzh8zv92qQsAEBHSHqv7j invoke [1]',
'Program Hn9KXdnBK6h2A7vZ2YqnnQdqzh8zv92qQsAEBHSHqv7j consumed 550 of 400000 compute units',
'Program Hn9KXdnBK6h2A7vZ2YqnnQdqzh8zv92qQsAEBHSHqv7j failed: invalid program argument'
],
computeUnitsUsed: 550
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.