Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
eth-saddle
Advanced tools
Saddle is a simple framework for developing Ethereum Smart Contracts. Think of it like a lean and mean version of truffle.
What saddle does
What saddle does not
To install saddle, simply create a new npm or yarn project and run:
yarn add eth-saddle
# or
npm install eth-saddle --save
After you've installed saddle, you can compile, test or deploy your contracts. See saddle help
for more information. See configuration
below for configuration help.
Let's assume you define a simple Ethereum contract:
contracts/MyContract.sol
pragma solidity ^0.5.12;
contract MyContract {
function myFunc() pure external returns (uint256) {
return 55;
}
}
Now, you can compile your contract with:
npx saddle compile
saddle compile
will compile your contracts and store the built output in ./build/contracts.json
. This is the raw output of solc compile.
After you've compiled, you can deploy your contracts:
npx saddle deploy -n development
This will deploy your comiled contracts to development (for this, you should have ganache-cli running). For more information on configuring your deployment for rinkeby or mainnet, see the configuration section below.
After you have deployed, you will also see the contract address listed in ./build/development.json
, if you want to keep track of your deployments.
Note: before testing, you currently have to compile your contracts. To run your tests, then, run:
npx saddle compile && npx saddle test
saddle test
runs your tests. To add tests, create a directory /tests
and add some simple tests, e.g.
tests/MyTest.js
describe('View', () => {
test('deploy and read contract', async () => {
let ctx = await deploy('MyContract', []);
expect(await call(ctx.methods.myFunc())).toEqual(55);
});
}
Saddle provides a few helper functions for your tests, which are:
web3
- A web3 instance connected to the chosen provideraccount
- The default account for web3accounts
- A list of unlocked accounts for web3deploy(contract: string, args: any[], sendOptions: SendOptions={})
- Deploys a contractcall(contract: Contract, method: string, arguments: any[], callOptions: CallOptions={})
- Call a function on a contractsend(contract: Contract, method: string, arguments: any[], sendOptions: SendOptions={})
- Send a transaction on a contractYou can really get by without using most of these functions (except maybe deploy), since they are light wrappers around web3 functions, but the wrappers will allow saddle to provide better helpers and diagnostics in the future.
Saddle comes with a tracing library that can analyze transaction receipts. This is useful in debugging and testing. For example:
test('balance has one read', async () => {
// Run the transaction (here, balanceOf) so we can trace it
let trxReceipt = await comp.methods.balanceOf(saddle.accounts[0]).send();
await saddle.trace(trxReceipt, {
constants: {
"account": saddle.accounts[0] // tracing code will note this as an address
},
preFilter: ({op}) => op === 'SLOAD', // filter all operations to find only SLOADs
// we can filter by source code if we want
// note: source code only available when running in `trace mode`
postFilter: ({source}) => !source || source.includes('balanceOf'),
execLog: (log) => {
log.show(); // show each load operation
},
exec: (logs, info) => {
expect(logs.length).toEqual(1); // make sure there's only one matching operation
}
});
});
The code above will trace and make sure only one Ethereum read operation was called in that operation. The logs (when run in trace mode) will look like this:
Log pc=503 op=SLOAD source=contracts/Token.sol:100[24-45]
Solidity uint balance = _balances[account];
↓
EVM Asm SLOAD[SHA3(CONCAT(account,0x4))]-> 0x1
That is, when the program counter (PC) reached 503, we did an SLOAD from line 100 of Token.sol (shown below). The SLOAD was based on the SHA3 of the account
address added to 0x4
(Solidity's fourth slot) and yielded a balance of 1 wei.
Trace Features:
constants
- Saddle's data analysis tool will note that these values should be tokenized. Note: saddle expects values like this to be globally unique (like addresses or hash results).preFilter
- Given a simple trace log object, return true to continue processing on that log. Each log will go through detailed tracing and it's good to remove irrelevant logs here.postFilter
- After each log has been analyzed and mapped to source code, you can add additional filters here.execLog
- Once per log, run the following (possibly async) function.exec
- Once per trace, run the following function with all logs passed in.If you have new features or analysis you'd like to add to tracing, feel free to open an issue or craft a PR. The goal is to make useful analysis tools to help bridge the mental model of Solidity to the Ethereum virtual machine.
Deploying a contract:
npx saddle deploy MyContract Arg0 Arg1 -n rinkeby
Verifying a contract on Etherscan:
npx saddle verify "{Etherscan API Key}" MyContract Arg0 Arg1 -n rinkeby
Matching an on-chain contract matches your local contract's compilation:
npx saddle match 0x... MyContract Arg0 -n rinkeby
You can also start a saddle console:
npx -n --experimental-repl-await saddle console
Saddle console on network development Web3ProviderEngine
> saddle
Saddle {
...
}
> .deploy Counter
Deploying contract Counter with args []
Deployed Counter at 0x81d2b78e483Ad6e9bc8e1a46F45434cFbad980B5
> await counter.methods.count().call()
0
Available commands:
.compile
- Recompile and reload contracts.contracts
- Show all contracts with constructor args.deployed
- Show all contracts deployed on this network.deploy <contract> <...args>
- Deploy a given contract.network
- Show given network.provider
- Show given providerYou can recompile contracts in the repl by running .compile
.
You can also run scripts from saddle. For instance, you can run:
npx saddle script myScript.js arg0 arg1
And then if you have a script such as:
// my_script.js
const [name, symbol] = args;
async function() {
let contract = await saddle.deploy('MyContract', [name, symbol]);
console.log(`Deployed MyContract to ${contract.address}`);
}();
This should open up the ability to create complex deployment scripts.
Saddle comes with reasonable default configuration, but you can override it. The core of the configuration is a list of "sources" for any given configuration-item, allowing the framework to look at say an environment variable for a provider, or if that is missing, a file with the provider information, or if that is missing, use a default http endpoint. This would be described as:
...
provider: [{env: "PROVIDER"}, {file: "~/.ethereum-provider"}, {http: "http://rinkeby.infura.io"}]
To set your own configuration, simply run: saddle init
and this will create a file saddle.config.js
. Make any changes to the configuration you need in that file
Please create an issue for any questions. In the interest of keeping saddle as simple as possible, we will not try to mimic all features of more complex frameworks-- so it's better to discuss first before submitting PRs.
Thanks and enjoy!
FAQs
Ethereum Smart Contract Saddle
The npm package eth-saddle receives a total of 71 weekly downloads. As such, eth-saddle popularity was classified as not popular.
We found that eth-saddle demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.