Key Solidity Commands/Illustrations
Useful foundation solidity commands - Understanding
LLL has been deprecated in late 2019Event : How to generate event when updating a variable
Sample code here under illustrate how to generate an event when we insert an input in the adopters array. You can use https://remix.ethereum.org to see how event are generated. Go on Remix Environment section and select VM (to use the Remix Blockchain Simulator). Select the good compiler version, compile the code, then deploy it with Remix. In the deployed contract section, select the deployed contract and insert an adopter by clicking on "adopt and put 1". Check on the rigth section and click on debut to see the detail. You will see in the logs section the value of the event generated:
[ { "from": "0xd4fc541236927e2eaf8f27606bd7309c1fc2cbee", "topic": "0x9bfa8a75e6c0508ff72126d8b916a6dcc0bfa9920fa37c6ad1b5db12b3218230", "event": "Triggeradoption", "args": { "0": "0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "1": "1", "_adopter": "0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "petId": "1", "length": 2 } } ]
Run this sample code to see the event generated on https://remix.ethereum.org
Inheritance
Heritance is like in Python Definition The derived contract inherite:
State Variable
Functions
Event
The code included in the base contract is copied in the derived contract at the moment of compilation. So the inherited byte code is copy in the derived SC.
Contract can inherite multiple base contracts. Functions in derived contract can overwrite functions defined in base contract. To overwrite a base function, the overwrite function must have the same name, input, input type and output. This apply for internal and external fucntions.
If herited contract constructor requires arguments, include them in derived contract constructor signature header.
Order of inheritance matter, define order from the most base like to to most derived.
Function, modifier and event names must be unique among contract and all base contract.
Polymorphism means that a function call (internal and external) always executes the function of the same name (and parameter types) in the most derived contract in the inheritance hierarchy.
Abstract contracts: can miss function implementation, but can be used as based contract. Contract that inherite abtract contract but doesn't implement all functions are also abstract contract.
Interface contract: similar to abtract contract but can not have any function implemented. They can not inherite from any contract. They are inherited by any contract, just as regular contract. They don't have:
They can not declare state variable (nor enum)
They can not declare a constructor
They cannot inherit from other contracts, but they can inherit from other interfaces
All declared functions must be external.
Additional URL:
Library and the Ethereum Package Manager
Library Definition: Libraries are contracts that do not have storage, they cannot hold ether and they cannot inherit or be inherited by other contracts. Libraries can be seen as implicit base contracts of the contracts that use them.
Exists for the purpose of code reuse
Allow library function to modify the states of the calling contract. Possible by using the delegatecall opcode on EVM
The library can define the struct data type, but it will not be saved in storage until it is actually implemented in a contract. This implemented struct can be passed to the library and modified, and the modifications will persist in the contracts’ storage
If the contracts deployed from the factory contract are declaring the same functions, moving the functions to a library can reduce the size of the contract created by the factory
Calling a library function from a contract is a bit more expensive than calling internal functions, so there is a trade-off to consider.
Package Management:
EthPM is essentially npm for Ethereum contracts. Truffle has support for EthPM so you can install a package with truffle install and the package name.
Like NPM, configuration options for EthPM go in a separate JSON file called
ethpm.json
https://www.ethpm.com
Usefull URL:
https://solidity.readthedocs.io/en/develop/contracts.html#libraries
Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused using the
DELEGATECALL
SmartContract System Design
Designing a voting system (Commit, Reveal approach)
Voter sign vote and submit the hash on blockchain
Then reveal the vote only if hash match what was commit during commit phase
See also the use case colony patform (example):
Poll clausing
At Closing all accounts are locked
High level design of it:
Use a Token Library (manage colony token)
Use a Voting Library (Contains poll and voting logic)
Libraries hold logic and generic contract hold data
Separation of concerns and allow for upgradability
Requirement for a poll are attribute in a data structure
Description, option for people to vote on (yes/no), start time, close time, poll status (create, active, resolved)
Each attribute is a mapping
Key is the hash of the pollId and the property
Value is a uint or string
Contract has also globla variable holding:
Poll count
options count for each poll
Poll life cycle
To store committed and not yet resolved vote, use a sorted double linked list
What secret voting looks like?
secret =sha3(salt, pollOptionId)
salt is additional random input data to obfuscate the vote
When the voter has calculated his vote secret, they summit their vote:
secret
pollId
previous timestamp,
previous pollId
Address locking:
if voted poll is closed
but they have still to reveal their vote
Usefull link:
Proof of existence SC - Sample
Based on https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05/
Proof of Existence is a service that verifies the existence of a document or file at a specific time via timestamped transactions
Step1: Connect to blockchain: using ganache-cli
Step2: Setup the Truffle Dev Framework
Step 3: Write the SC
Find more info on truffle migrate on https://www.trufflesuite.com/docs/truffle/getting-started/running-migrations
Step 4: Interact with SC
Step 5: Updating the code of the SC
Step 6: Deploy on Testnet
Use MetaMask (save your param in .secret in the project) !! Do not do this on production with real value, this is for simulation lab only
To perform transaction on Testnet, we need some Ether. Get free Rinkeby ether by going to this website
To deploy contracts to the testnet using Truffle without having to sync a local node, you can use Infura. Infura allows you to access a fully synced Ethereum node via their API. We will use their API to deploy our contracts to the Rinkeby testnet. Go to the Infura website and sign up for a free account.
Step 7: Test the SC deployed on Rinkeby SmartContract
Connect to https://remix.ethereum.org with Chrome to support Metamask
Select injected Web3 Metamask, select Rinkebey 4 account
Select address where we publish the SC/ 0x1C908c985a0036637E04bdb6E9EeaA9966E7fb4d
Then interact and select "notarize"
Multi-Signature Wallet Sample
Sample Multi Signature Wallet
Reference on https://github.com/ConsenSys-Academy/multisig-wallet-exercise/blob/master/Multisig_wallet_info.md and https://github.com/ConsenSysMesh/MultiSigWallet
Follow steps on https://github.com/ConsenSys-Academy/multisig-wallet-exercise
A multisignature wallet is an account that requires some m-of-n quorum of approved private keys to approve a transaction before it is executed. In Ethereum, multisignature wallets are implemented as a smart contract, that each of the approved external accounts sends a transaction to in order to "sign" a group transaction.
SmartContract Best practice Security Guidlines: https://consensys.github.io/smart-contract-best-practices/
Use Remix:
Reminder of messages on Remix:
Yellow triangles are warning messages
Red circles are error messages and will prevent your contract from compiling.
Personal Nota: Code will be on: /Users/lemaima/Documents/devTest/multisig-wallet-exercise/contracts/MultiSignatureWallet.sol
// The indexed keyword in the event declaration makes the event easily // searchable and is useful when building user interfaces that need to parse // lots of events.
// When we are modifying the state of a function, it is a good practice to log an event
Another multisig wallet: https://github.com/ConsenSysMesh/MultiSigWallet/blob/master/MultiSigWalletWithDailyLimit.sol
Other useful URL on MultisigWallet:
Debugging Truffle Testing
Source is on: https://github.com/ConsenSys-Academy/truffle-test-debugging
Truffle is really useful for writing and running automated tests on your smart contracts. We will use https://www.trufflesuite.com/docs/truffle/getting-started/debugging-your-contracts
Sample Exercice One - Illustration Purpose Only
The excercice here under is for illustration purpose only.
https://github.com/CA-bootcamp-s19/simple-bank-exercise-
IPConvergence/settings/accesshttps://github.com/CA-bootcamp-s19
https://github.com/CA-bootcamp-s19/simple-bank-exercise-IPConvergence
TRAVIS CLI Tool will be used to validate the testCode automatically: https://travis-ci.com/github/CA-bootcamp-s19/simple-bank-exercise-IPConvergence
Sample Exercice 2 - Illustration Purpose only
This second exercice here under is for illustration purpose only.
https://github.com/ConsenSys-Academy/supply-chain-exercise
https://github.com/CA-bootcamp-s19/supply-chain-exercise-IPConvergence
https://github.com/CA-bootcamp-s19/supply-chain-exercise-IPConvergence/settings/access
https://travis-ci.com/github/CA-bootcamp-s19/supply-chain-exercise-IPConvergence
https://pocketsense.com/purpose-escrow-account-4344.html
As ref:
https://github.com/CA-bootcamp-s19
In the field of inventory management, a stock keeping unit (SKU) is a distinct type of item for sale, such as a product or service, and all attributes associated with the item type that distinguish it from other item types. For a product, these attributes could include manufacturer, description, material, size, color, packaging, and warranty terms. When a business takes inventory of its stock, it counts the quantity it has of each SKU.
A stock-keeping unit (SKU) is a scannable bar code to help vendors automatically track the movement of inventory.
SKU are retailers code that tracks product, manufactor and price (so this is more than simple product serial number bare code).
// Solidity code statement address(0)
which is the initial value of a variable of type address
Ethereum and End-User
Introduction to Web3
The problem with Internet today is your identity and your data that you don't control the access and sharing. The cost of the web is subsidized by the value of your data. This model needs to change. We need an ethical internet to foster innovation and collaboration.
It is time to decentralize the internet (go outside the power of Google, Facebook, Amazon...) and move to version 3:
A web of ethical collaboration, rewarding the contributor
A web where data is not censored
A web where data can be autenticated to their originator
A web where users own their data
Other interesting URL on the topic:
From web 1.0, to 2.0 going to 3.0: https://media.consensys.net/a-warm-welcome-to-web3-89d49e61a7c5 (very good historical artical)
Web3.js javascript API reference documentation: https://web3js.readthedocs.io/en/v1.2.9/ This is the Ethereum Javascrip API. web3.js is a collection of libraries that allow you to interact with a local or remote ethereum node using HTTP, IPC or WebSocket.
Web3.js Javascript Libraries
There are a variety of common JavaScript libraries that you can use to connect to Ethereum.
Truffle: Truffle will connect to a running blockchain specified in the truffle-config.js file, manage deployments via migration scripts and information stored in the truffle artifacts. Truffle provides contract abstractions for interacting with your contracts. Following URL are the basis API explanation, very important: https://www.trufflesuite.com/docs/truffle/reference/contract-abstractions
Web3.js
Web3.js is one of the most popular JavaScript libraries in Ethereum dApp development. There are 2 versions:
web3.js 1.X: https://web3js.readthedocs.io/en/v1.3.0/
web3.js 0.X: https://github.com/ethereum/web3.js/blob/0.20.7/DOCUMENTATION.md (MetaMask is still using that old version !!!)
Install Ganache-GUI: https://www.trufflesuite.com/ganache
Connect your Metamask (via Chrome) to Ganache-GUI
Launch Ganache-GUI
In Metamask, select Network, new custom RPC
Enter http://localhost:7545
Then go on Ganache and copy the private key of the first account
Go back to Metamask and select import account and past the private key
Then on the chrome browser, browse: https://remix.ethereum.org, go in the section on the left "Deploy and Run" with the Ethereum logo, select environment and select Web3Provider. Then change the local host to localhost:7545 (so change port)
Then Remix should be connected to Metamask
Publish a SmartContract and see if you see a block created on ganache-GUI
Then go back to Chrome browser, go in menu: view -> developer -> javascript console.
MetaMask has injected the web3.js library in the browser.
So in the Chrome javascript console, type web3 and you will see the object
To connect the account
Side Node on Metamask:
If you are following along in your browser, you will also see that in the "currentProvider" property, the "selectedAddress" is undefined or null. Metamask does not provide access to the account address by default. If you type ethereum.enable()
in the console, Metamask will pop open asking you if you'd like to connect. Connecting will make this account information accessible to the current page.
You can look at how to connect to contract with web3.js with https://web3js.readthedocs.io/en/v1.2.0/web3-eth-contract.html#web3-eth-contract
Ether.js
Ether.js library is on https://docs.ethers.io/v5/
We will continue to use Metamask for signing transaction and connecting to the local Ganache-GUI Blockchain
We will use Chrome with Javascript console open and inject command there, and use the Ether.js library that will be injected by a Web page (I use the consensys page here above)
In the browser console, you can connect ethers.js to the current network by accessing the provider given by Metamask, then set it is as the "signer". Metamask injects the provider as "web3.currentProvider", but since we changed the web3 object to use web3.js v1.0, the provider is accessible at "web3.givenProvider".
Doc:
https://docs.ethers.io/v5/api/ (the reference doc)
As a developer, you can use different JavaScript libraries to interact with Ethereum blockchains. Many of the JavaScript libraries do many of the same things, but they may handle transaction signers or providers differently or have different ways of connecting to contracts and listening to events. The library you choose is primarily a matter of personal preference.
Connecting web3.js to contract
For this exercice, we are going to connect to the following contract for the test https://gist.github.com/ConsenSys-Academy/6d93a805ce0e90d8a793a4eb6e69b4c5
Go in view a Chrome -> view -> developer -> Javascript console, so you can interact via javascript to web3
Connect your Metamask in the same chrome to Rinkeby and swap to your Rinkeby account that has test ether (often people forget to swap manually account and they use accound of the local Ganache-GUI that is not defined on Rinkeby with Ether received via faucet
Open you Chrome browser and browse the consensys page :https://courses.consensys.net/courses/take/blockchain-developer-bootcamp-registration-2020/texts/14509940-8-1-2-connecting-web3-js-to-a-contract
Check that the web3 object instance has well been injected in the browser javascript console by the Metamask app and check that the provider is well the address of your account on Rinkeby
web3.currentProvider.selectedAddress -> you should see the address of your Rinkeby account selected in your metamask client
Building Truffle for the Web
As reference for inspiration: https://www.trufflesuite.com/tutorials/pet-shop#creating-a-ui-to-interact-with-our-smart-contract
We are going to build a Browser App interface to interact with SC.
Update to Metamask
Metamask automatically injected the web3 object into the browser window object, making it available for any application to use it. Metamask now provides the option to no longer automatically inject the web3 object, something called "privacy mode". Which requires that dapps ask permission to view users’ accounts. Dapps should update their code to support this feature.
dapps must now request access to user accounts by calling a new method on the provider: ethereum.enable(). This method returns a Promise that’s either resolved with user accounts after user approval, or rejected with an Error after user rejection.
Integrating with React
The following sample exercice is usefull to understand how to integrate with React framework: https://www.trufflesuite.com/boxes/react
Other usefull pages:
Rimble UI
Rimble is a React component library that makes creating Web3 applications in react much easier. The library is under active development by the ConsenSys Design team.
Other usefull URL on the subject:
https://rimble.consensys.design/components/rimble-ui/ToastMessage (to notify user that a transaction is done)
Smart Contracts Pitfalls, Testing, and Debugging
Covered on this section:
Writing tests for Solidity smart contracts in Javascript and Solidity using the Truffle framework
Smart contract best practices
Smart contract exploits and dangers
Optimizing Gas
Go over a safety checklist of things to consider before deploying your contracts
Writing Test
Test Driven Development: Developers write tests first, then implement functions to make the tests pass. We write test for:
Verify correct Behaviour
Consider Edge Cases
Consider range of possible user input
No necessarily for finding bugs only:
It is about contract behaviour
TDD is about behaviour defined first through unit test
Test in Truffle can be writen in Solidity or Javascript
Testing contract should not extend any existing contract
With Truffle, we import:
Assert.sol library (from Truffle, planned for test)
DeployedAddresses.sol (from Truffle, planned for test): The addresses of your deployed contracts (i.e., contracts that were deployed as part of your migrations) are available through the
truffle/DeployedAddresses.sol
library.+ the contract we want to test
Remark regarding the test contract:
Contract name should start with T
Function test must beging with t (test...)
Kooks:
There exists also provided hooks like in Mocha Javascript Testing Framework
Use to setup and teardown before and after each test
It is possible for the setup function to exceed the gaz limit, then play with beforeEachAgain() hook to solve that problem
Test with Javascript: (see example pet-shop-tutorial/test/testAdoption.test.js)
Truffle use the Mocha Framework and chai for assertion
use contract() instead of describe()
before each contract(), the contract are redeply, meaning state variable rest also (clean state)
you can still use describe() when contract() is not necessary
Other good references for testing writing:
Writing Solidity test with Truffle: https://www.trufflesuite.com/docs/truffle/testing/writing-tests-in-solidity
Writing Javascript test with Truffle: https://www.trufflesuite.com/docs/truffle/testing/writing-tests-in-javascript
Throws test: https://www.trufflesuite.com/tutorials/testing-for-throws-in-solidity-tests : Truffle 3 brings forth Solidity unit testing, which means one can now test contracts in Solidity itself. This is a boon to contract developers, as there are several reasons why it's useful to have Solidity tests in addition to Truffle’s Javascript tests.
Catch Error in Javascript test: https://ethereum.stackexchange.com/questions/48627/how-to-catch-revert-error-in-truffle-test-javascript
Catching Javascript error
Try catch
This tryCatch function will first execute the try block that will wait for the promise that it received to resolve. If it resolves without throwing an error, then the last line of the try block will throw an empty error. So no matter what, whether the promise succeeds or fails, the catch block will be executed, receiving whatever error information was thrown in the try block.
Special error handling
We can make this error handling function even more specific so that it can tell us why a specific error is being thrown. The VM exception messages provide details as to why an exception was thrown. For example, whether the exception was due to a revert, if the transaction ran out of gas, if there was an invalid JUMP or another invalid OPCODE, if there was a stack overflow or underflow or if there was a static state change. We can add these details to our errorString to catch specific cases.
In the catch block, the first assertion statement checks whether the error message contains any information. If the promise successfully executed, this first assertion statement will fail and will let you know that it "Expected a VM exception but did not get one." So "error!=0" -> it executes the texte after. If the first assertion statement passes, and the error message does contain information, then the second assertion statement will be executed. The statement will search the error message for a predefined string.
How to include in our .js test?
Now to include this in your Javascript tests, you can save this file called something like "exceptionHelpers.js" in your Truffle test directory. You can import specific functions and include them in your tests! This test will pass as long as the buyTickets() function throws a revert!
Other References on the subject:
Open Zeppelin Test helper: https://github.com/OpenZeppelin/openzeppelin-test-helpers
Smart Contract Best Practices
Different than other programing language:
Cost of failure can be high
Change can be difficult
Move Slow and be carefull
Prepare for failure:
Code will have bug
Setup a circuit breaker design pattern
Manage amount of money at risk with rate limiting or caps
Setup upgrade path for bug fixes and improvement
Roll-out very carefully
Catch Bug before release
Automated testing
Use Testnets
Time locking Alpha and beta release
3th party security audit
But bounties (Prime)
Keep contract simple
Complexity => more bugs
Moduralize the code, with simple block
Use Audited and battle tested code when possible
Prefer clarity than performance
Only use blockchain when necessary
Unique Environment
Know the env
Be very carefull when calling external contract
Function are public
malicious actors will try calling your function in a way you didn't intend or foresee
contract data is public
Limits proper to this sytem (contrains)
gaz price
block gaz limit
Fundamental trade-offs
trade-offs between engineering and security
Ideal system is modular, reuse code, and support upgradable component
Rigidity versus upgradability
on SW dev perspective, upgradability support is good but on SC it highers the maleability, complexity and surface attack
For simple function, simplicity is focus before upgradability support
Monolithic versus Modular
A single Monolithic SC keep all data local, identifiable and controlable, can make code review easier
Modular can be easier to maintain on SW point of view
Code duplication versus reuse
Use proved, deployed, audited code when possible
Other usefull reference:
Exploits and Dangers
There is a SmarContract Weakness Classification Registry (SWC) under: https://swcregistry.io
The Smart Contract Weakness Classification Registry (SWC Registry) is an implementation of the weakness classification scheme proposed in EIP-1470. It is loosely aligned to the terminologies and structure used in the Common Weakness Enumeration (CWE) while overlaying a wide range of weakness variants that are specific to smart contracts.
The goals of this project are as follows:
Provide a straightforward way to classify security issues in smart contract systems.
Define a common language for describing security issues in smart contract systems' architecture, design, or code.
Serve as a way to train and increase performance for smart contract security analysis tools.
Re-entracy Attack (SWC 107) https://swcregistry.io/docs/SWC-107
Problematic because calling external contracts passes control flow to them. The called contract may take over the control flow and end up calling the smart contract function again in a recursive manner (you could have then an un-ending loop or abuse loop). If you can’t remove the external call, the next simplest way to prevent this attack is to do the internal work before making the external function call.
How to mitigate:
Good idea to handle your internal contract state changes before calling external contracts
A more complex solution could implement mutual exclusion, or a mutex. This allows you to lock a state and only allow changes by the owner of the lock.
Additionnal complementary info on: https://consensys.github.io/smart-contract-best-practices/known_attacks/#race-conditions42
Transaction Ordering and Timestamp Dependence (SWC-114) https://swcregistry.io/docs/SWC-114
Here we focus on how transactions are included in the blockchain and considerations around the process.
Transactions that are broadcast to the network but have not yet been included in a block are in the mempool. Miners choose the order in which to include transactions from the mempool into a block that they are mining. Also, since transactions are in the mempool before they make it into a block, anyone can know what transactions are about to occur on the network. This can be problematic for things like decentralized markets. Protecting against this is difficult and you will likely need to devise contract specific solutions. Decentralized markets can mitigate concerns by implementing batch auctions (enchère) or using a pre-commit scheme, where the details are submitted after the transaction is committed.
Integer Overflow and Underflow (SWC-101) https://swcregistry.io/docs/SWC-101
Integers can underflow or overflow in the EVM (SWC-101). This happens when an arithmetic value oversteps the minimum or maximum size of a type. Reference
An overflow/underflow happens when an arithmetic operation reaches the maximum or minimum size of a type. For instance if a number is stored in the uint8 type, it means that the number is stored in a 8 bits unsigned number ranging from 0 to 2^8-1. In computer programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of bits – either larger than the maximum or lower than the minimum representable value.
Underflow is a similar situation, but when a uint goes below its minimum value it will be set to its maximum value.
Denial of Service with Failed Call (SWC-113) https://swcregistry.io/docs/SWC-113
External calls can fail accidentally or deliberately, which can cause a DoS condition in the contract. To minimize the damage caused by such failures, it is better to isolate each external call into its own transaction that can be initiated by the recipient of the call. This is especially relevant for payments, where it is better to let users withdraw funds rather than push funds to them automatically (this also reduces the chance of problems with the gas limit).
Remediation: it is recommended to follow call best practices:
Avoid combining multiple calls in a single transaction, especially when calls are executed as part of a loop
Always assume that external calls can fail
Implement the contract logic to handle failed calls
Denial of Service by Block Gas Limit or startGas (SWC-128) https://swcregistry.io/docs/SWC-128
When smart contracts are deployed or functions inside them are called, the execution of these actions always requires a certain amount of gas, based of how much computation is needed to complete them. The Ethereum network specifies a block gas limit and the sum of all transactions included in a block can not exceed the threshold.
Programming patterns that are harmless in centralized applications can lead to Denial of Service conditions in smart contracts when the cost of executing a function exceeds the block gas limit. Modifying an array of unknown size, that increases in size over time, can lead to such a Denial of Service condition.
There is a limit to how much computation can be included in a single Ethereum block, currently 10,000,000 gas worth
How transaction are generally ordered in block (Miner can decide), but this is a trend: https://ethereum.stackexchange.com/questions/6107/what-is-the-default-ordering-of-transactions-during-mining/6111#6111
Remediation:
Caution is advised when you expect to have large arrays that grow over time. Actions that require looping across the entire data structure should be avoided.
If you absolutely must loop over an array of unknown size, then you should plan for it to potentially take multiple blocks, and therefore require multiple transactions.
Force Sending Ether
Another danger is using logic that depends on the contract balance. Be aware that it is possible to send ether to a contract without triggering its fallback function. Using the selfdestruct
function on another contract and using the target contract as the recipient will force the destroyed contract’s funds to be sent to the target.
It is also possible to pre-compute a contracts address and send ether to the address before the contract is deployed.
The contract’s balance will be greater than 0 when it is finally deployed.
Complementary interesting links:
A survey of Attack on Ethereum SC/ https://eprint.iacr.org/2016/1007.pdf
List of known bugs: https://solidity.readthedocs.io/en/develop/bugs.html
SC Weakness: https://swcregistry.io
Testing hack under game: https://solidity-05.ethernaut.openzeppelin.com
Game to hack Eth SC to learn security: https://capturetheether.com
Optimizing Gaz
Reducing the gas consumed by a contract is important in two situations:
Cost of deploying a contract
Cost to call the contract functions
The Solidity optimizer tries to improve the efficiency of your contract as much as possible during compile time
Gaz cost per opcode: https://docs.google.com/spreadsheets/d/1n6mRqkBz3iWcOlRem_mO09GtSKEKrAsfO7Frgx18pNU/edit#gid=0
Short Circuit Rules
The operators ||
and &&
apply the common short-circuiting rules. This means that in the expression f(x) || g(y)
, if f(x)
evaluates to true, g(y)
will not be evaluated even if it may have side-effects.
Expensive operations in a loop
Modifying storage variables in a loop can be very expensive and should be avoided unless absolutely necessary. How can this function be improved, given that loop is a storage variable? Here is the source file.
Reduce the number of loops
Zero loops is ideal, but sometimes you just have to loop. Since loops are expensive, can you reduce the number of loops in your functions?
Fixed size byte arrays
The type byte[]
is an array of bytes, but due to padding rules, it wastes 31 bytes of space for each element (except in storage). It is better to use the bytes
type instead. see https://solidity.readthedocs.io/en/latest/types.html#fixed-size-byte-arrays
Other good document references:
Optimizing your solidity contract gas usage: https://medium.com/coinmonks/optimizing-your-solidity-contracts-gas-usage-9d65334db6c7
Paper on under-optimize SC devouring your money https://arxiv.org/pdf/1703.03994.pdf
How to write SC that optimize Gas: https://medium.com/better-programming/how-to-write-smart-contracts-that-optimize-gas-spent-on-ethereum-30b5e9c5db85
Safety Checklist
SWC Registry
For a comprehensive, maintained list of smart contract weaknesses, along with test cases and examples of vulnerable smart contracts, check out the SWC Registry. This is a community maintained project and includes most, if not all of the well known vulnerabilities and hacks, with contract samples and suggestions for how to address weaknesses.
Additional Resources:
Logic Bugs :
run unit test to avoid logic bug
following standard coding and best practices
avoid complex rule and implementation
Recursive call
Can be dangerous, re-entrancy attack with external SC call (this was exploited in the DAO attack)
Integer arithmetic overflow
integers will automatically and silently wrap if too small or too large
max for uint = 2^256-1 (which is a quite huge number)
Usint uint8 -> can be dangerous if user can insert data without control of his value
Poison Data
Like a user changing a state variable so that it oveflows.
Assume user will input data we don't expect
validate and sanatize user input data
What contract expose to the world
Be aware
! Soliditiy functions default to public
Any code that go to production should be audited
All code and data (state variable) are public on blockchain (all storage variable are public)
Making them private only make them not accessible to SC directly
!!! Private storage variable can still be observed by external blockchain user
Miner Vulnerabilities
Miners can manipulate block timestamp and which transaction can be in a block, during a limited windows time frame. Sometimes better to include a timestamp inside the SC state variable
Malicious Admin
Dangerous to allocat to specific address power on SC. Better to work with multisig contract.
Off-chain safety
Use tradditional Web security best practices:
HTTPS
2 factors authentication
encryption
Cross-chain Replay attack
When hardforks are happening on a blockchain, any transaction on one is valid on the other one. So one transaction posted on one blockchain could be run on the other one, without our consent, because valid by default
When hardforks are happening on a blockchain, any transaction on one is valid on the other one. So one transaction posted on one blockchain could be run on the other one, without our consent, because valid by default
TX Origin and Gas limit
!!! Use msg.sender
in place of tx.origin
Looping over a undetermined range of a array could be dangerous. We could exeed block gas max limit
Run Test for gas usage in our SC tests
Limit the lenght of user supplied data
Security Analysis Tools
A quick and easy way to check your Solidity code for common bugs is to use security analysis tools. Static analysis tools will parse your code and highlight potential security vulnerabilities.
Code online check tool: https://tool.smartdec.net
The more popular security tool: https://mythx.io
MythX is the premier security analysis API for Ethereum smart contracts. It detects many common Solidity and EVM bytecode vulnerabilities. This makes it attractive for developers and auditors alike. It can be used right away with integrations for Truffle, Remix, Brownie, or from the system CLI. There are also libraries (https://docs.mythx.io/en/latest/building-security-tools/index.html#language-bindings) available as a starting point for building custom security tools such as IDE extensions and CI scripts.
MythX is a security analysis API that allows anyone to create purpose-built security tools for smart contract developers. Tools built on MythX integrate seamlessly into the development environments and continuous integration pipelines used throughout the Ethereum ecosystem.
Exercice to do:
Create an account on https://mythx.io/
First install the MythX security plugin for Truffle Framework: https://github.com/ConsenSys/truffle-security
Generate the Mythx API key: Generate your API key in the tools section of the MythX dashboard.
The key can be passed to Truffle either via the MYTHX_API_KEY
environment variable or the --apiKey
command line argument. For security reasons it is recommended to always pass the token through an environment variable, e.g. defined in the settings of a Continuous Integration (CI) server or a shell script that can be sourced from.
Set the following enviromment variables to your API key (add this to your .bashrc
or .bash_profile
for added convenience):
To test Mythx, we will use the following Github project: https://github.com/ConsenSys-Academy/simple-coin In the Visual Studio, go to source control on the left, '...' source, clone, github "consensys-Academy/simple-coin
MythX can also be used on Remix!
Additional Resources
MythX: https://mythx.io
Mythril: https://github.com/ConsenSys/mythril
MythX Truffle Pluggin: https://github.com/ConsenSys/truffle-security
tx.origin Attack Demo
Ref Material:
tx.origin
is a global variable in Solidity which returns the address of the account that sent the transaction. Using the variable for authorization could make a contract vulnerable if an authorized account calls into a malicious contract. A call could be made to the vulnerable contract that passes the authorization check since tx.origin
returns the original sender of the transaction which in this case is the authorized account.
The global variable tx.origin
in Solidity always references the address of the original sender of the transaction, of the full call chain. See the reference in the docs here. This is different than message.sender
in that message.sender
references the address of the sender of the current call.
You should never use tx.origin
in Solidity for authorization
Additional References:
Denial of service attack example
Shows how a contract may be susceptible to a denial of service attack by an unexpected revert (SWC-113)
External calls can fail accidentally or deliberately, which can cause a DoS condition in the contract. To minimize the damage caused by such failures, it is better to isolate each external call into its own transaction that can be initiated by the recipient of the call. This is especially relevant for payments, where it is better to let users withdraw funds rather than push funds to them automatically (this also reduces the chance of problems with the gas limit).
Re-entrancy attack example
A reentrancy attack -> (https://swcregistry.io/docs/SWC-107) l
Integer over/under flow example
Shows what an integer overflow vulnerability (https://swcregistry.io/docs/SWC-101) looks like. This type of attack is easily avoidable by using a SafeMath library such as this, that provides safety checks and will revert on error.
MythX
MythX is a smart contract security service for Ethereum.
Advanced Ethereum Topics
We will cover the following points:
Common Smart contract design patterns
Designing upgradable smart contract systems
What are Oracles, and how do you use one?
Using the Ethereum Name Service
An introduction to IPFS
Formal Verification and smart contracts
SmartContract Design Pattern
We will go over some of the most common design patterns that developers use when writing smart contracts.
Good Principle: Fail early and fail loud
Restricting Access
You cannot prevent people or computer programs from reading your contracts’ state. The state is publicly available information for anyone with access to the blockchain. However, you can restrict other contracts’ access to the state by making state variables private.
You can restrict function access so that only specific addresses are permitted to execute functions. This is useful for allowing only designated users, or other contracts to access administrative methods, such as changing ownership of a contract, implementing an upgrade or stopping the contract.
More on access control with Zepplin: https://docs.openzeppelin.com/contracts/2.x/access-control
Auto-Deprecation
The auto deprecation design pattern is a useful strategy for closing contracts that should expire after a certain amount of time. This can be useful when running alpha or beta testing for your smart contracts.
!!! Remember that using timestamps such as the now keyword are subject to manipulation by the block miners in a 30-second window.
Mortal
Function to kill a SC. Implementing the mortal design pattern means including the ability to destroy the contract and remove it from the blockchain. You can destroy a contract using the selfdestruct
keyword. The function to do it is often called kill. It takes one parameter which is the address that will receive all of the funds that the contract currently holds. As an irreversible action, restricting access to this function is important.
As compl info sample: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/56de324afea13c4649b00ca8c3a3e3535d532bd4/contracts/access/Ownable.sol
Withdrawal pattern (pull over push payment)
See also: https://gist.github.com/critesjosh/80d41928db2310684bc7660aa45873da, there is a separation of function logic. The split()
function handles the accounting and divides the msg.value
sent with the transaction. Another function, withdraw()
, allows accounts to transfer their balance from the contract to their account.
This pattern is also called the withdrawal pattern. It protects against re-entrancy and denial of service attacks that we will cover in the next lesson.
Circuit Breaker
Circuit Breakers are design patterns that allow contract functionality to be stopped. This would be desirable in situations where there is a live contract where a bug has been detected. Freezing the contract would be beneficial for reducing harm before a fix can be implemented.
In a situation such as this, you would also want to restrict access to the accounts that can modify the stopped state variable, maybe to the contract owner (such as multisig wallet) or a set of admins.
State Machine
Contracts often act as a state machine, where the contract has certain states in which it behaves differently and different functions can and should be called. A function call often ends a stage and moves the contract to the next stage (especially if the contract models interaction). It is also common that some stages are automatically reached at a certain point in time.
Speed Bump
Speed bumps slow down actions so that if malicious actions occur, there is time to recover.
Used to limit issue of DAO: https://github.com/blockchainsllc/DAO
The Ethereum Name System
Resolve Human readable name to machine readable identifiers:
Name to Ethereum Address
Name to IPFS Hash
Name to Swarm Hash
It aims at solving the same problem as DNS for Internet (Name -> IP Address)
ENS offer Ethereum address resolution but the system could be extensed, enabling further resources to be resolved in the future.
ENS Architecture:
Registry SmartContract:
Single Contract
List domain, subdomain and data
The Data include the owner of the domain that can be an external account or contract
Store the address of the Resolver SC for the domain and the Time to live
Domain Owner can
set the resolver they want to use
can transfer the ownership of the domain
can change also ownership of subdomain
Resolver SmartContract:
Translate name to machine readable identifier
Any contract that implement the standard resolver can be setup as resolver
Each record type (Ethereum, ipfs) defines a method the resolver must implement
New Record type can be submitted via EIP (Ethereum improvement proposal) to community
Additional Resources:
IPFS
IPFS stand for the Inter-planetary file system
Hashes in IPFS start with "Qm..."
The js-ipfs library allows you to use IPFS without having to run a local IPFS node
It aims to replace HTTP by addressing file content (with hashes) rather than file locations
It uses p2p protocols, making it a decentralized network
It complements blockchain nicely, as it allows immutable, off-chain data storage
Other benefits include bandwidth saving for servers, potential content availability improvements, censorship and deletion resistance and data deduplication
IPFS is a distributed Peer to Peer file system:
no servers
only node
nodes store files and cryptographic hashes of files
Files are adressed by hashes
A single network sharing git objects
Good complement to Ethereum for decentralized applications:
Maintain Data Integrity of the resources that it references (change it content data -> change in hash so change in address)
Peer to peer and decentralized, so no SPOC and resilient
Cheaper Data Storage than blockchain
Store Data on IPFS
Store IPFS hash on SC
Additional Resources:
https://ipfs.io
Upgradable contract
Bugs are inevitable -> upgradability strategy needed for SC
Modular design -> Enable to upgrade some component and not all
Plan for upgrade contract is important, but lots of research on it
2 approaches for managing upgradable SC:
Maintain a registry SC storing the address of the latest version of SC
Or use a contract (Proxy) that forward Data and call to the correct SC
Upgrade take time:
Incorporate security measure, like circuit breaker
Registry SC:
Store the latest contract address -> this requires user make a query for every time they want to use a SC to know the latest address
Disadvantage: if user not use it, it is pushing data on old SC version + how to manage data migration
Forward Data and Call SC:
Avoid problem of registry contract
User only interact with User relay contract
Attention on storage point:
Must be the same between upgrade
Additional Resources:
https://eips.ethereum.org/EIPS/eip-2535 -> The diamond standard a new way to upgrade SC
Oracle with Rhombus
Oracle provides off-chain data into SC
Oracle are like an API for Blockchain
You could build your own oracle, but some cons:
How can a user be sure he can trust your oracle?
Some 3th party Oracle Service provider:
Oraclize (a leading one for Ethereum, bitcoin...)
Smartcontract.com
Oracle logic is "it this, then I give you that info"
Recursive queries are possible
An Oracle queries require:
Data Source Type
URL
Wolfram Alpha (https://www.wolframalpha.com) (Retrieve an answer to question )
IPFS (retrive a file from an IPFS location)
Random byte
Computation (provide the result of arbitrary computation)
Query (to the Data Source type)
Authenticity Proof type (optional)
This proof enables to reduce the trust user must have in Oracle
From withing a SC, we can make queries to Oracle SC, passing data source and query to it. The Oracle SC then answer to the _fallback() function of the calling SC that can catch in variable the answer and perform update of its state variable. In the calling SC definition, we use contract Co2Level is usingOraclize {...}
We can add proof of authenticity check
Additional Resources:
Provable Things Documentation -> Very usefull to read!
Rhombus network
In the context of blockchain, oracles are an industry term for an information source that delivers real world data to smart contracts on a blockchain. Oracle providers must ensure truthfulness of the data provided:
First off, the real world data must be obtained from a trusted place. There is no blockchain system to guarantee data accuracy, so this data is often obtained from a trusted and verified source.
Second, the oracle should also provide proof that the data has not been tampered with, either by external parties, or the oracle service provider itself.
We will sample how this works thanks to a step by step sample code on how to incorporate real world data into your smart contracts with the Rhombus Lighthouse Delivery method -> https://github.com/RhombusNetwork/tutorial
Rhombus provides oracle data through a mechanism called a lighthouse. In simple terms, a lighthouse is an address where a single integer value that contains off-chain data is stored. Rhombus ensures the value is updated periodically, and can provide guarantees that the value is correct. -> https://rhombus.network
In this case, there is a random number generator lighthouse already deployed on Rinkeby, and you must access this lighthouse from your casino project smart contract (which will also be deployed on Rinkeby)
Formal Verification
The goal is to make writing secure smart contracts as easy and accessible as possible. One route to this goal is via formal verification. From Wikipedia, formal verification is the act of proving or disproving the correctness of intended algorithms underlying a system with respect to a certain formal specification or property, using formal methods of mathematics. Said another way, it is a way to prove that a program is correct for all inputs. This can ensure that a hacker cannot modify the contract to an unintended state.
Formal verification is a method to prove a program correct for all inputs
MythX is also able to formally verify smart contracts. This guide gives more details on how to formally verify a smart contract in Remix using the MythX analysis API.
In Remix, go to the section plugin and search for Mythx, add it. Then in settings, add API and login /Password of your Mythx Account. Then you can run basic test.
Other usefull links:
Zero Knowledge Proof
First production on ZKP is from the 1980, some initial publications can be found on https://amturing.acm.org/award_winners/goldwasser_8627889.cfm
The goal of zero-knowledge proofs (ZKPs) is for a verifier to be able to convince themselves that a prover possesses knowledge of a secret parameter, called a witness, satisfying some relation, without revealing the witness to the verifier or anyone else.
Zero-knowledge proofs are currently being researched as solutions to two main issues in public blockchains:
Privacy: All essential information within a blockchain network must be public. ZKPs allow users to verify / prove certain elements of information (such as the answer to a crossword puzzle) while not revealing the information itself (to not give the answer to someone else). Certain tools, such as AZTEC, promise to use ZKPs to provide channels which shield the entire nature of certain transactions from the public blockchain while still using the public blockchain's security promises
Scalability: As blockchain networks grow, the amount of data they require to be maintained grows as well. ZKPs compress large amounts of data into compact, verifiable proofs, a characteristic scalability researchers hope to use to dramatically reduce the data required to maintain security on a public blockchain.From ZCash:“Succinct” zero-knowledge proofs (SNARKs, STARKs) can be verified within a few milliseconds, with a proof length of only a few hundred bytes even for statements about programs that are very large.
A common way Zero-Knowledge Proofs are used in blockchain is as follows. A Verifier will take the piece of data to be verified and put it through a private process (ZK-SNARK or STARK, for example) which produces a program called a Proof Circuit. This Proof Circuit can then be posted openly (such as in a Smart Contract) as it reveals no meaningful information about the nature of the data it represents. A Prover can then use the Proof Circuit to irrefutably prove they know the piece of data by publicly "solving" the Proof Circuit, a process that also reveals nothing about the nature of the data.
zk-SNARKs
Succinct Non-Interactive ARgument of Knowledge, or SNARKs, were first widely implemented on a blockchain by ZCash, a fork of Bitcoin. Ethereum introduced SNARK capacity with the Byzantium fork by including precompiled contracts that allowed efficient SNARK verification on-chain. SNARKs are being discussed in terms of privacy (as in ZCash) and scalability (as in SNARK roll-ups)
Other links:
zk-STARKs
Scalable and Transparent ARgument of Knowledge, or STARKs, share a similar fundamental ideas with SNARKs but differ in execution. Their development and advocacy is done chiefly by STARKware, a private company led by Eli Ben Sasson, with assistance from the Ethereum Foundation.
No trust setup and faster than SNARK
Other links:
AZTEC
Anonymous Zero-Knowledge Transactions with Efficient Communication, or AZTEC, is a way of executing confidential transactions on a public blockchain like Ethereum. The AZTEC Protocol is a series of op-codes (based on range proofs) embedded in smart contract libraries deployed by the AZTEC Protocol team (a private company acquired by ConsenSys) on Ethereum. Using a combination of these op-codes along with an off-chain Javascript library, the AZTEC Protocol team has developed a design pattern they call the "AZTEC Note," which allows for individuals to generate and transfer their own version of these notes on-chain without revealing internal transactions to external parties.
Other references:
ZKP Tutorials
"Hello World" of zk-SNARKS with Zokrates (ZoKrates is a toolbox for zkSNARKs on Ethereum. It helps you use verifiable computation in your DApp, from the specification of your program in a high level language to generating proofs of computation to verifying those proofs in Solidity.)
More Resources
Introduction to zk-SNARKS with Examples (article)
Not-so-gentle Introduction to the PCP Theorem (PCP Theorem underpins many ZKPs) (article)
The Math behind STARKs (abstract but still technical) (5-part article series)
Etherum 2.0
Launch of Ethereum in 2015, First roadmpa https://blog.ethereum.org/2015/12/24/understanding-serenity-part-i-abstraction/
If we were to think of the Ethereum network as a house, launch of Ethereum mainnet was the building of the house and everyone moving in. Network forks are the patches, repairs and additional features to address challenges that arise from more people moving into the house. The upgrade to Ethereum 2.0 ("Serenity" on the roadmap) will be akin to building an entirely new foundation and house to accommodate the next generation of network growth.
Imagine the Ethereum 2.0 house being beside the Ethereum 1.x home. At first, there will be a path connecting the two. Ultimately, Ethereum 2.0 will expand to include Ethereum 1.x within it.
Ethereum 2.0 has three phases:
Phase 0 - Beacon Chain (Proof-of-Stake)
Phases 0 is the implementation of a Proof-of-Stake consensus mechanism for Ethereum. The blockchain secured by Phase 0's PoS mechanism is called the Beacon Chain. Miners for the Beacon Chain are called validators.
Phase 0 is the phase most public one now, as it's currently undergoing public testing and there are multiple companies developing software for it. Here is a list of the main validator clients:
Teku — Java-based client developed by ConsenSys Software
Prysm — Go-based client developed by Prysmatic Labs
Lighthouse — Rust-based client developed by Sigma Prime
Lodestar — Javascript-based client
Nimbus — Nim-based client developed by Status
The Medalla testnet was the first, public, multi-client testnet available. You can check out its progress here and join the testnet by following these steps.
Phase 1 - Shards (Data Availability and Coordination)
Database sharding is used in conventional computer programming to increases scalability of large systems. From this article. Ethereum 2.0 leverages traditional database sharding to decrease the amount of memory needed to maintain the full state of the network. Originally meant to be 1024 shards, the current spec will produce 64 database shards. Each of these shards will have their own validators. They will periodically check into the beacon chain using crosslinks, which is a summary of the state of that shard and the only representation of the shard on the Beacon Chain.
Phase 2 - Execution Environments (Computation)
The final phase of Ethereum 2.0 deals with the execution environments present on each shard. in Ethereum 1.x, the execution environment is the Ethereum Virtual Machine, a Turing-complete programming language that provides a universal computation environment for all in the network to use.
However, this universality comes at an efficiency cost. The EVM is slow compared to modern processing languages. Phase 2 addresses this processing cost by using a version of WebAssembly, a new type of code developed by Mozilla. It allows code written in C, C++ or Rust but executed in the browser to run at near-native speeds. (For more information about the implications of WebAssembly for the broader web, please see this video: "Rust, WebAssembly and the Future of Serverless")
In Phase 2, each shard will be allowed a unique execution environment. While at least one will be running the EVM (for sake of continuity), it's possible others will be running execution environments (EEs) for Libra, Bitcoin, or any other blockchain network.
Research is still developing in this area and the specs have not been frozen. If you'd like to try an experimental execution environment prototyping tool for Ethereum 2.0, please see Scout.
The Beacon Chain (that connect the shard chains):
In August 2020, the Ethereum 2.0 developers launched the Medalla testnet. It is the first multi-client public testnet for Ethereum 2.0 Beacon Chain. It's exciting because you can get involved to run a Beacon Chain client and stake test-Ether to mimic the actions of a validator. All of this is to test the clients and find major issues before the launch of the actual Beacon Chain.
Near the end of the course, we'll be doing a walkthrough of setting up and staking on the Medalla testnet using multiple clients.
Relevant URL:
Ethereum Yellow paper: https://ethereum.github.io/yellowpaper/paper.pdf
Eth2.0 Spec: https://github.com/ethereum/eth2.0-specs
To follow progress on Eth2: https://hackmd.io/@benjaminion/eth2_news/https%3A%2F%2Fhackmd.io%2F%40benjaminion%2Fwnie2_200822
Additional Topics
LLL (Low-level Lisp-like Language)
LLL has been deprecated in late 2019. Lisp Like Language (LLL) is a low level language similar to Assembly. It is meant to be very simple and minimalistic; essentially just a tiny wrapper over coding in EVM directly. LLL has direct access to storage and memory of the EVM so you can determine exactly where your data sits. When you use an EVM opcode in LLL, it translates directly to the bytecode representation of that opcode. In fact, all EVM opcodes are available to LLL.
Generally LLL binaries are about 30 to 40% smaller than the equivalent in Solidity. LLL also uses prefix notation, where operators are placed to the left of their operands.
Example implemenation of SC in LLL: https://github.com/benjaminion/LLL_erc20#erc20lll-an-implementation-of-ethereum-erc20-tokens-in-lll
The registry contract of the Ethereum Name service (ENS) was written in LLL mainly because of the gas savings due to its size and the brevity of its code: https://github.com/ensdomains/ens
Introduction to Vyper
Vyper is an experimental, contract-oriented, pythonic programming language that targets the Ethereum Virtual Machine. Beware, Vyper is not ready for production use cases.Vyper is not trying to be a replacement for Solidity. It is meant to be a more security focused smart contract programming language and will likely not be able to do everything that Solidity can.
Other references:
Writing SC in Vyper
Sample banking code in VIper: https://github.com/ConsenSys-Academy/simple-bank-vyper
You need to install the Vyper compiler yourself for Truffle to be able to compile Vyper contracts.
Installing Vyper on Linux is as simple as
Otherwise, consult the docs.
Ethereum Improvement proposal (EIP)
Ethereum is an open source project with no one company or organization that controls the direction of the project. There is an open governance model where everyone is free to propose and discuss changes to the system. The EIP system is the forum to do this. You can view the EIP website here.
The explanation of the EIP Process: https://eips.ethereum.org/EIPS/eip-1
There are several different stages that an EIP can be in. Draft EIPs are works in progress, are open for consideration and discussed on GitHub. Accepted EIPs can be expected to be included in the next hard fork upgrade. You can see a list of the accepted EIPs for the Byzantium upgrade in EIP 609. Final EIPs are proposals that have already been adopted and deferred EIPs are not being considered for immediate adoption, but may be considered again in the future.
An EIP includes the following sections:
Preamble (metadata)
Simple summary
Abstract - A short description of the issue
Motivation - Why is the existing protocol inadequate
Specification - Describes the syntax and semantics of the new feature
Rationale - Why did you make these design decisions?
Backwards compatibility - Explain any backward incompatibilities and how they will be addressed
Test Cases - These are mandatory for EIPs proposing consensus changes
Implementation - What does an implementation of the EIP look like? This section must be completed before the EIP is given the status “Final”.
ERC= Ethereum request for Comment
The development of tokens on Ethereum is under active development. Explore these EIPs to follow the development of token standards.
Additional Resources:
Additional Tips and Tricks
A transaction hash on Ethereum is calculated as followed:
So when you call a smartcontract method, you can not within that method access the transaction hash, because you need first to sign that transaction, this is the chicken and eggs problem. You can via a second transaction after access that info.
Last updated