Merge pull request #4146 from PatrickAlphaC/v0.6-update-solidity
[solidity/en]
BIN
images/solidity/copy-address.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
images/solidity/metamask-kovan.png
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
images/solidity/remix-add-token.png
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
images/solidity/remix-choose-file.png
Normal file
After Width: | Height: | Size: 464 KiB |
BIN
images/solidity/remix-compile.png
Normal file
After Width: | Height: | Size: 739 KiB |
BIN
images/solidity/remix-deploy.png
Normal file
After Width: | Height: | Size: 738 KiB |
BIN
images/solidity/remix-interact.png
Normal file
After Width: | Height: | Size: 774 KiB |
BIN
images/solidity/remix-solidity.png
Normal file
After Width: | Height: | Size: 336 KiB |
BIN
images/solidity/remix-testnet.png
Normal file
After Width: | Height: | Size: 850 KiB |
BIN
images/solidity/send-link.png
Normal file
After Width: | Height: | Size: 118 KiB |
@ -6,6 +6,7 @@ contributors:
|
|||||||
- ["Joseph Chow", ""]
|
- ["Joseph Chow", ""]
|
||||||
- ["Bhoomtawath Plinsut", "https://github.com/varshard"]
|
- ["Bhoomtawath Plinsut", "https://github.com/varshard"]
|
||||||
- ["Shooter", "https://github.com/liushooter"]
|
- ["Shooter", "https://github.com/liushooter"]
|
||||||
|
- ["Patrick Collins", "https://gist.github.com/PatrickAlphaC"]
|
||||||
---
|
---
|
||||||
|
|
||||||
Solidity lets you program on [Ethereum](https://www.ethereum.org/), a
|
Solidity lets you program on [Ethereum](https://www.ethereum.org/), a
|
||||||
@ -18,7 +19,7 @@ state variables, functions, and common data types. Contract-specific features
|
|||||||
include modifier (guard) clauses, event notifiers for listeners, and custom
|
include modifier (guard) clauses, event notifiers for listeners, and custom
|
||||||
global variables.
|
global variables.
|
||||||
|
|
||||||
Some Ethereum contract examples include crowdfunding, voting, and blind auctions.
|
Some Ethereum contract examples include crowdfunding, voting, [decentralized finance](https://defipulse.com/), and blind auctions.
|
||||||
|
|
||||||
There is a high risk and high cost of errors in Solidity code, so you must be very careful to test
|
There is a high risk and high cost of errors in Solidity code, so you must be very careful to test
|
||||||
and slowly rollout. WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY UP TO
|
and slowly rollout. WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY UP TO
|
||||||
@ -32,6 +33,66 @@ popular design patterns.
|
|||||||
As Solidity and Ethereum are under active development, experimental or beta
|
As Solidity and Ethereum are under active development, experimental or beta
|
||||||
features are typically marked, and subject to change. Pull requests welcome.
|
features are typically marked, and subject to change. Pull requests welcome.
|
||||||
|
|
||||||
|
# Working with Remix and Metamask
|
||||||
|
|
||||||
|
One of the easiest ways to build, deploy, and test solidity code is by using the:
|
||||||
|
|
||||||
|
1. [Remix Web IDE](https://remix.ethereum.org/)
|
||||||
|
2. [Metamask wallet](https://metamask.io/).
|
||||||
|
|
||||||
|
To get started, [download the Metamask Browser Extension](https://metamask.io/).
|
||||||
|
|
||||||
|
Once installed, we will be working with Remix. The below code will be pre-loaded, but before we head over there, let's look at a few tips to get started with remix. Load it all by [hitting this link](https://remix.ethereum.org/#version=soljson-v0.6.6+commit.6c089d02.js&optimize=false&evmVersion=null&gist=f490c0d51141dd0515244db40bbd0c17&runs=200).
|
||||||
|
|
||||||
|
1. Choose the Solidity compiler
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
2. Open the file loaded by that link
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
3. Compile the file
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
4. Deploy
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
5. Play with contracts
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
You've deployed your first contract! Congrats!
|
||||||
|
|
||||||
|
You can test out and play with the functions defined. Check out the comments to learn about what each does.
|
||||||
|
|
||||||
|
|
||||||
|
## Working on a testnet
|
||||||
|
|
||||||
|
Deploying and testing on a testnet is the most accurate way to test your smart contracts in solidity.
|
||||||
|
To do this let's first get some testnet ETH from the Kovan testnet.
|
||||||
|
|
||||||
|
[Pop into this Gitter Channel](https://gitter.im/kovan-testnet/faucet) and drop your metamask address in.
|
||||||
|
|
||||||
|
In your metamask, you'll want to change to the `Kovan` testnet.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
You'll be given some free test Ethereum. Ethereum is needed to deploy smart contracts when working with a testnet.
|
||||||
|
|
||||||
|
In the previous example, we didn't use a testnet, we deployed to a fake virtual environment.
|
||||||
|
When working with a testnet, we can actually see and interact with our contracts in a persistent manner.
|
||||||
|
|
||||||
|
To deploy to a testnet, on the `#4 Deploy` step, change your `environment` to `injected web3`.
|
||||||
|
This will use whatever network is currently selected in your metamask as the network to deploy to.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
For now, please continue to use the `Javascript VM` unless instructed otherwise. When you deploy to a testnet, metamask will pop up to ask you to "confirm" the transaction. Hit yes, and after a delay, you'll get the same contract interface at the bottom of your screen.
|
||||||
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// First, a simple Bank contract
|
// First, a simple Bank contract
|
||||||
// Allows deposits, withdrawals, and balance checks
|
// Allows deposits, withdrawals, and balance checks
|
||||||
@ -40,7 +101,7 @@ features are typically marked, and subject to change. Pull requests welcome.
|
|||||||
/* **** START EXAMPLE **** */
|
/* **** START EXAMPLE **** */
|
||||||
|
|
||||||
// Declare the source file compiler version
|
// Declare the source file compiler version
|
||||||
pragma solidity ^0.4.19;
|
pragma solidity ^0.6.6;
|
||||||
|
|
||||||
// Start with Natspec comment (the three slashes)
|
// Start with Natspec comment (the three slashes)
|
||||||
// used for documentation - and as descriptive data for UI elements/actions
|
// used for documentation - and as descriptive data for UI elements/actions
|
||||||
@ -67,7 +128,7 @@ contract SimpleBank { // CapWords
|
|||||||
event LogDepositMade(address accountAddress, uint amount);
|
event LogDepositMade(address accountAddress, uint amount);
|
||||||
|
|
||||||
// Constructor, can receive one or many variables here; only one allowed
|
// Constructor, can receive one or many variables here; only one allowed
|
||||||
function SimpleBank() public {
|
constructor() public {
|
||||||
// msg provides details about the message that's sent to the contract
|
// msg provides details about the message that's sent to the contract
|
||||||
// msg.sender is contract caller (address of contract creator)
|
// msg.sender is contract caller (address of contract creator)
|
||||||
owner = msg.sender;
|
owner = msg.sender;
|
||||||
@ -84,7 +145,7 @@ contract SimpleBank { // CapWords
|
|||||||
// no "this." or "self." required with state variable
|
// no "this." or "self." required with state variable
|
||||||
// all values set to data type's initial value by default
|
// all values set to data type's initial value by default
|
||||||
|
|
||||||
LogDepositMade(msg.sender, msg.value); // fire event
|
emit LogDepositMade(msg.sender, msg.value); // fire event
|
||||||
|
|
||||||
return balances[msg.sender];
|
return balances[msg.sender];
|
||||||
}
|
}
|
||||||
@ -92,7 +153,7 @@ contract SimpleBank { // CapWords
|
|||||||
/// @notice Withdraw ether from bank
|
/// @notice Withdraw ether from bank
|
||||||
/// @dev This does not return any excess ether sent to it
|
/// @dev This does not return any excess ether sent to it
|
||||||
/// @param withdrawAmount amount you want to withdraw
|
/// @param withdrawAmount amount you want to withdraw
|
||||||
/// @return The balance remaining for the user
|
/// @return remainingBal
|
||||||
function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
|
function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
|
||||||
require(withdrawAmount <= balances[msg.sender]);
|
require(withdrawAmount <= balances[msg.sender]);
|
||||||
|
|
||||||
@ -153,7 +214,8 @@ assert(c >= a); // assert tests for internal invariants; require is used for use
|
|||||||
// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
|
// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
|
||||||
|
|
||||||
|
|
||||||
// No random functions built in, use other contracts for randomness
|
// No random functions built in, you can get a pseduo-random number by hashing the current blockhash, or get a truely random number using something like Chainlink VRF.
|
||||||
|
// https://docs.chain.link/docs/get-a-random-number
|
||||||
|
|
||||||
// Type casting
|
// Type casting
|
||||||
int x = int(b);
|
int x = int(b);
|
||||||
@ -584,9 +646,35 @@ reveal(100, "mySecret");
|
|||||||
// All data to start of time is stored in blockchain, so
|
// All data to start of time is stored in blockchain, so
|
||||||
// anyone can observe all previous data and changes
|
// anyone can observe all previous data and changes
|
||||||
|
|
||||||
|
// E. Oracles and External Data
|
||||||
|
// Oracles are ways to interact with your smart contracts outside the blockchain.
|
||||||
|
// They are used to get data from the real world, send post requests, to the real world
|
||||||
|
// or vise versa.
|
||||||
|
|
||||||
|
// Time-based implementations of contracts are also done through oracles, as
|
||||||
|
// contracts need to be directly called and can not "subscribe" to a time.
|
||||||
|
// Due to smart contracts being decentralized, you also want to get your data
|
||||||
|
// in a decentralized manner, other your run into the centralized risk that
|
||||||
|
// smart contract design matter prevents.
|
||||||
|
|
||||||
|
// To easiest way get and use pre-boxed decentralized data is with Chainlink Data Feeds
|
||||||
|
// https://docs.chain.link/docs/get-the-latest-price
|
||||||
|
// We can reference on-chain reference points that have already been aggregated by
|
||||||
|
// multiple sources and delivered on-chain, and we can use it as a "data bank"
|
||||||
|
// of sources.
|
||||||
|
|
||||||
|
// You can see other examples making API calls here:
|
||||||
|
// https://docs.chain.link/docs/make-a-http-get-request
|
||||||
|
|
||||||
|
// And you can of course build your own oracle network, just be sure to know
|
||||||
|
// how centralized vs decentralized your application is.
|
||||||
|
|
||||||
|
// Setting up oracle networks yourself
|
||||||
|
|
||||||
// D. Cron Job
|
// D. Cron Job
|
||||||
// Contracts must be manually called to handle time-based scheduling; can create external
|
// Contracts must be manually called to handle time-based scheduling; can create external
|
||||||
// code to regularly ping, or provide incentives (ether) for others to
|
// code to regularly ping, or provide incentives (ether) for others to
|
||||||
|
//
|
||||||
|
|
||||||
// E. Observer Pattern
|
// E. Observer Pattern
|
||||||
// An Observer Pattern lets you register as a subscriber and
|
// An Observer Pattern lets you register as a subscriber and
|
||||||
@ -628,23 +716,26 @@ contract SomeOracle {
|
|||||||
|
|
||||||
// F. State machines
|
// F. State machines
|
||||||
// see example below for State enum and inState modifier
|
// see example below for State enum and inState modifier
|
||||||
|
```
|
||||||
|
|
||||||
|
Work with the full example below using the [`Javascript VM` in remix here.](https://remix.ethereum.org/#version=soljson-v0.6.6+commit.6c089d02.js&optimize=false&evmVersion=null&gist=3d12cd503dcedfcdd715ef61f786be0b&runs=200)
|
||||||
|
|
||||||
|
```javascript
|
||||||
// *** EXAMPLE: A crowdfunding example (broadly similar to Kickstarter) ***
|
// *** EXAMPLE: A crowdfunding example (broadly similar to Kickstarter) ***
|
||||||
// ** START EXAMPLE **
|
// ** START EXAMPLE **
|
||||||
|
|
||||||
// CrowdFunder.sol
|
// CrowdFunder.sol
|
||||||
pragma solidity ^0.4.19;
|
pragma solidity ^0.6.6;
|
||||||
|
|
||||||
/// @title CrowdFunder
|
/// @title CrowdFunder
|
||||||
/// @author nemild
|
/// @author nemild
|
||||||
contract CrowdFunder {
|
contract CrowdFunder {
|
||||||
// Variables set on create by creator
|
// Variables set on create by creator
|
||||||
address public creator;
|
address public creator;
|
||||||
address public fundRecipient; // creator may be different than recipient
|
address payable public fundRecipient; // creator may be different than recipient, and must be payable
|
||||||
uint public minimumToRaise; // required to tip, else everyone gets refund
|
uint public minimumToRaise; // required to tip, else everyone gets refund
|
||||||
string campaignUrl;
|
string campaignUrl;
|
||||||
byte constant version = 1;
|
byte version = "1";
|
||||||
|
|
||||||
// Data structures
|
// Data structures
|
||||||
enum State {
|
enum State {
|
||||||
@ -654,7 +745,7 @@ contract CrowdFunder {
|
|||||||
}
|
}
|
||||||
struct Contribution {
|
struct Contribution {
|
||||||
uint amount;
|
uint amount;
|
||||||
address contributor;
|
address payable contributor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// State variables
|
// State variables
|
||||||
@ -684,10 +775,10 @@ contract CrowdFunder {
|
|||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CrowdFunder(
|
function crowdFund(
|
||||||
uint timeInHoursForFundraising,
|
uint timeInHoursForFundraising,
|
||||||
string _campaignUrl,
|
string memory _campaignUrl,
|
||||||
address _fundRecipient,
|
address payable _fundRecipient,
|
||||||
uint _minimumToRaise)
|
uint _minimumToRaise)
|
||||||
public
|
public
|
||||||
{
|
{
|
||||||
@ -712,7 +803,7 @@ contract CrowdFunder {
|
|||||||
);
|
);
|
||||||
totalRaised += msg.value;
|
totalRaised += msg.value;
|
||||||
|
|
||||||
LogFundingReceived(msg.sender, msg.value, totalRaised);
|
emit LogFundingReceived(msg.sender, msg.value, totalRaised);
|
||||||
|
|
||||||
checkIfFundingCompleteOrExpired();
|
checkIfFundingCompleteOrExpired();
|
||||||
return contributions.length - 1; // return id
|
return contributions.length - 1; // return id
|
||||||
@ -736,7 +827,7 @@ contract CrowdFunder {
|
|||||||
public
|
public
|
||||||
inState(State.Successful)
|
inState(State.Successful)
|
||||||
{
|
{
|
||||||
fundRecipient.transfer(this.balance);
|
fundRecipient.transfer(address(this).balance);
|
||||||
LogWinnerPaid(fundRecipient);
|
LogWinnerPaid(fundRecipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,6 +857,11 @@ contract CrowdFunder {
|
|||||||
}
|
}
|
||||||
// ** END EXAMPLE **
|
// ** END EXAMPLE **
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Some more functions.
|
||||||
|
|
||||||
|
```javascript
|
||||||
// 10. OTHER NATIVE FUNCTIONS
|
// 10. OTHER NATIVE FUNCTIONS
|
||||||
|
|
||||||
// Currency units
|
// Currency units
|
||||||
@ -837,18 +933,27 @@ someContractAddress.callcode('function_name');
|
|||||||
|
|
||||||
## Additional resources
|
## Additional resources
|
||||||
- [Solidity Docs](https://solidity.readthedocs.org/en/latest/)
|
- [Solidity Docs](https://solidity.readthedocs.org/en/latest/)
|
||||||
|
- [Chainlink Beginner Tutorials](https://docs.chain.link/docs/beginners-tutorial)
|
||||||
- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices)
|
- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices)
|
||||||
- [Superblocks Lab - Browser based IDE for Solidity](https://lab.superblocks.com/)
|
- [Superblocks Lab - Browser based IDE for Solidity](https://lab.superblocks.com/)
|
||||||
- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/)
|
- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/)
|
||||||
- [Browser-based Solidity Editor](https://remix.ethereum.org/)
|
- [Browser-based Solidity Editor](https://remix.ethereum.org/)
|
||||||
- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity)
|
- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity)
|
||||||
- [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/)
|
- [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/)
|
||||||
|
- [Chainlink Documentation](https://docs.chain.link/docs/getting-started)
|
||||||
|
|
||||||
|
## Smart Contract Development Frameworks
|
||||||
|
- [Hardhat](https://hardhat.org/)
|
||||||
|
- [Brownie](https://github.com/eth-brownie/brownie)
|
||||||
|
- [Truffle](https://www.trufflesuite.com/)
|
||||||
|
|
||||||
## Important libraries
|
## Important libraries
|
||||||
- [Zeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/): Libraries that provide common contract patterns (crowdfuding, safemath, etc)
|
- [Zeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts): Libraries that provide common contract patterns (crowdfuding, safemath, etc)
|
||||||
|
- [Chainlink](https://github.com/smartcontractkit/chainlink): Code that allows you to interact with external data
|
||||||
|
|
||||||
## Sample contracts
|
## Sample contracts
|
||||||
- [Dapp Bin](https://github.com/ethereum/dapp-bin)
|
- [Dapp Bin](https://github.com/ethereum/dapp-bin)
|
||||||
|
- [Defi Example](https://github.com/PatrickAlphaC/chainlink_defi)
|
||||||
- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
|
- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
|
||||||
- [ConsenSys Contracts](https://github.com/ConsenSys/dapp-store-contracts)
|
- [ConsenSys Contracts](https://github.com/ConsenSys/dapp-store-contracts)
|
||||||
- [State of Dapps](http://dapps.ethercasts.com/)
|
- [State of Dapps](http://dapps.ethercasts.com/)
|
||||||
@ -862,6 +967,7 @@ someContractAddress.callcode('function_name');
|
|||||||
- [Solidity Style Guide](http://solidity.readthedocs.io/en/latest/style-guide.html): Ethereum's style guide is heavily derived from Python's [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide.
|
- [Solidity Style Guide](http://solidity.readthedocs.io/en/latest/style-guide.html): Ethereum's style guide is heavily derived from Python's [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide.
|
||||||
|
|
||||||
## Editors
|
## Editors
|
||||||
|
- [Remix](https://remix.ethereum.org/)
|
||||||
- [Emacs Solidity Mode](https://github.com/ethereum/emacs-solidity)
|
- [Emacs Solidity Mode](https://github.com/ethereum/emacs-solidity)
|
||||||
- [Vim Solidity](https://github.com/tomlion/vim-solidity)
|
- [Vim Solidity](https://github.com/tomlion/vim-solidity)
|
||||||
- Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
|
- Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
|
||||||
|