mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-24 10:01:38 +00:00
Many minor updates
This commit is contained in:
parent
1f4738cbc7
commit
700f3e7a1c
@ -14,7 +14,7 @@ As Solidity and Ethereum are under active development, experimental or beta feat
|
|||||||
```javascript
|
```javascript
|
||||||
// Let's start with a simple Bank contract, before diving into to the key components of the language
|
// Let's start with a simple Bank contract, before diving into to the key components of the language
|
||||||
|
|
||||||
// START EXAMPLE
|
// ** START EXAMPLE **
|
||||||
// Start with a Natspec comment (the three slashes) that can be used
|
// Start with a Natspec comment (the three slashes) that can be used
|
||||||
// for documentation - and as descriptive data for UI elements
|
// for documentation - and as descriptive data for UI elements
|
||||||
/// @title A simple deposit/withdrawal bank built on Bitcoin
|
/// @title A simple deposit/withdrawal bank built on Bitcoin
|
||||||
@ -29,8 +29,7 @@ contract AcmeBank {
|
|||||||
mapping (address => uint) balances;
|
mapping (address => uint) balances;
|
||||||
|
|
||||||
// the 'public' makes 'owner' externally readable by users or contracts
|
// the 'public' makes 'owner' externally readable by users or contracts
|
||||||
// (but not writeable), the 'constant' means this value to be
|
// (but not writeable) -
|
||||||
// changed after initialization
|
|
||||||
address public owner;
|
address public owner;
|
||||||
|
|
||||||
// Constructor, can receive one or many variables here
|
// Constructor, can receive one or many variables here
|
||||||
@ -40,13 +39,13 @@ contract AcmeBank {
|
|||||||
owner = msg.sender; // msg.sender refers to the address of the contract creator
|
owner = msg.sender; // msg.sender refers to the address of the contract creator
|
||||||
}
|
}
|
||||||
|
|
||||||
function deposit(uint balance) {
|
function deposit(uint balance) public {
|
||||||
balances[msg.sender] += msg.value; // no need for "this." or "self." in front of the state variable
|
balances[msg.sender] += msg.value; // no need for "this." or "self." in front of the state variable
|
||||||
|
|
||||||
return balances[msg.sender]; // msg.sender refers to the contract caller
|
return balances[msg.sender]; // msg.sender refers to the contract caller
|
||||||
}
|
}
|
||||||
|
|
||||||
function withdraw(uint withdrawAmount) returns (uint remainingBalance) {
|
function withdraw(uint withdrawAmount) public returns (uint remainingBalance) {
|
||||||
if(balances[msg.sender] >= withdrawAmount) {
|
if(balances[msg.sender] >= withdrawAmount) {
|
||||||
balances[msg.sender] -= withdrawAmount;
|
balances[msg.sender] -= withdrawAmount;
|
||||||
|
|
||||||
@ -58,7 +57,8 @@ contract AcmeBank {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's good practice to have a remove function, which disables this contract - but does mean that users have to trust the owner
|
// It's good practice to have a remove function, which disables this
|
||||||
|
// contract - but does mean that users have to trust the owner
|
||||||
function remove() {
|
function remove() {
|
||||||
if(msg.sender == owner) { // Only let the contract creator do this
|
if(msg.sender == owner) { // Only let the contract creator do this
|
||||||
suicide(owner); // suicide makes this contract inactive, and returns funds to the owner
|
suicide(owner); // suicide makes this contract inactive, and returns funds to the owner
|
||||||
@ -71,29 +71,35 @@ contract AcmeBank {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fallback function
|
// Fallback function
|
||||||
// This function is called if invalid data is sent or ether without data;
|
// The fallback function is called if none of the other functions matches the given function identifier.
|
||||||
|
// It is often meant to be called when invalid data is sent or ether without data.
|
||||||
// Added so that ether sent to this contract is reverted if the contract fails
|
// Added so that ether sent to this contract is reverted if the contract fails
|
||||||
// otherwise, the sender loses their money; you should add this in most contracts
|
// otherwise, the sender loses their money; you should add this in most contracts
|
||||||
function () { throw; }
|
function () { throw; }
|
||||||
}
|
}
|
||||||
// END EXAMPLE
|
// ** END EXAMPLE **
|
||||||
|
|
||||||
// Now let's go through the basics of Solidity
|
// Now let's go through the basics of Solidity
|
||||||
|
|
||||||
// 1. DATA TYPES
|
// 1. DATA TYPES AND ASSOCIATED METHOD
|
||||||
// uint is the data type typically used for currency (there are no doubles
|
// uint is the data type typically used for currency (there are no doubles
|
||||||
// or floats) and for dates
|
// or floats) and for dates
|
||||||
uint x;
|
uint x;
|
||||||
int constant a = 8; // int of 256 bits, cannot be changed after instantiation
|
|
||||||
|
|
||||||
|
// with 'constant', the compiler replaces each occurence with the acutal value
|
||||||
|
// int of 256 bits, cannot be changed after instantiation
|
||||||
|
int constant a = 8;
|
||||||
|
int256 constant a = 8; // same effect as line above, here the 256 is explict
|
||||||
|
|
||||||
|
// For both int and uint, you can explicitly set space in steps of 8
|
||||||
|
// e.g., int8, int16
|
||||||
uint8 b;
|
uint8 b;
|
||||||
int64 c;
|
int64 c;
|
||||||
// int256 is same as int
|
|
||||||
// For both int and uint, you can explicitly set space in steps of 8,
|
|
||||||
// e.g., int8, int16
|
|
||||||
uint248 e;
|
uint248 e;
|
||||||
|
|
||||||
// Type casting
|
// Type casting
|
||||||
int x = int(b)
|
int x = int(b);
|
||||||
|
|
||||||
bool b = true; // or do 'var b = true;' for inferred typing
|
bool b = true; // or do 'var b = true;' for inferred typing
|
||||||
|
|
||||||
@ -123,13 +129,14 @@ var a = true;
|
|||||||
|
|
||||||
// by default, all values are set to 0 on instantiation
|
// by default, all values are set to 0 on instantiation
|
||||||
|
|
||||||
// Delete can be called on most types, and will set the values to 0
|
// Delete can be called on most types, and will set the values to 0 by assignment
|
||||||
uint x = 5;
|
uint x = 5;
|
||||||
delete(x); // x is now 0
|
delete(x); // x is now 0
|
||||||
|
|
||||||
// 2. DATA STRUCTURES
|
// 2. DATA STRUCTURES
|
||||||
// Arrays
|
// Arrays
|
||||||
bytes32[] names;
|
bytes32[5] nicknames; // static array
|
||||||
|
bytes32[] names; // dynamic array
|
||||||
uint newLength = names.push("John"); // adding returns new length of the array
|
uint newLength = names.push("John"); // adding returns new length of the array
|
||||||
// Length
|
// Length
|
||||||
names.length; // get length
|
names.length; // get length
|
||||||
@ -168,29 +175,39 @@ delete(b); // set all values to 0, except any mappings
|
|||||||
enum State { Created, Locked, Inactive };
|
enum State { Created, Locked, Inactive };
|
||||||
State public state; // Declare variable from enum
|
State public state; // Declare variable from enum
|
||||||
state = State.Created;
|
state = State.Created;
|
||||||
|
// enums can be explicitly converted to ints
|
||||||
|
|
||||||
|
// Data locations: Memory vs. storage - all complex types (arrays, structs) have a data location
|
||||||
|
// 'memory' does not persist, 'storage' does
|
||||||
|
// Default is 'storage' for local and state variables; 'memory' for function parameters
|
||||||
|
|
||||||
// 3. Variables of note
|
// 3. Variables of note
|
||||||
// storage - A persistent storage hash (does not need to be declared)
|
// ** this **
|
||||||
storage['abc'] = 'def'; // maps 256 bit words to 256 bit words
|
this; // the address of the current contract
|
||||||
|
// 'balance' often used at the end of a contracts life to send the
|
||||||
|
// remaining balance to a party
|
||||||
|
this.balance;
|
||||||
|
this.someFunction(); // calls a function externally (via a message call, not via an internal jump)
|
||||||
|
|
||||||
// tx - This transaction
|
// ** msg - The current message received by the contract ** **
|
||||||
tx.origin // address, sender of the transaction
|
|
||||||
tx.gasprice // uint, gas price of the transaction
|
|
||||||
|
|
||||||
// msg - The current message received by the contract
|
|
||||||
msg.sender; // address, The address of the sender
|
msg.sender; // address, The address of the sender
|
||||||
msg.value; // uint, The amount of gas provided to this contract in wei
|
msg.value; // uint, The amount of gas provided to this contract in wei
|
||||||
msg.data // bytes, complete call data
|
msg.data; // bytes, complete call data
|
||||||
|
msg.gas; // remaining gas
|
||||||
|
|
||||||
// balance of the current contract (both contract and external accounts
|
// ** tx - This transaction **
|
||||||
// have balances) - often used at the end of a contracts life to send the
|
tx.origin; // address, sender of the transaction
|
||||||
// remaining balance to a party
|
tx.gasprice; // uint, gas price of the transaction
|
||||||
this.balance
|
|
||||||
// block
|
// ** block - Information about the current block **
|
||||||
now // uint, current time, alias for block.timestamp
|
now // uint, current time, alias for block.timestamp
|
||||||
block.number // uint, current block number
|
block.number; // uint, current block number
|
||||||
block.difficulty // uint, current block difficulty
|
block.difficulty; // uint, current block difficulty
|
||||||
block.blockhash(1) // returns bytes32, only provides for most recent 256 block
|
block.blockhash(1); // returns bytes32, only provides for most recent 256 blocks
|
||||||
|
block.gasLimit();
|
||||||
|
|
||||||
|
// ** storage - A persistent storage hash (does not need to be declared) **
|
||||||
|
storage['abc'] = 'def'; // maps 256 bit words to 256 bit words
|
||||||
|
|
||||||
// 4. FUNCTIONS AND MORE
|
// 4. FUNCTIONS AND MORE
|
||||||
// A. Functions
|
// A. Functions
|
||||||
@ -236,7 +253,7 @@ function b() {
|
|||||||
|
|
||||||
// B. Events
|
// B. Events
|
||||||
// Events are an easy way to notify external listeners that something changed
|
// Events are an easy way to notify external listeners that something changed
|
||||||
// You typically decalre them after your contract parameters
|
// You typically declare them after your contract parameters
|
||||||
event Sent(address from, address to, uint amount);
|
event Sent(address from, address to, uint amount);
|
||||||
|
|
||||||
// You then call it in a function, when you want to trigger it
|
// You then call it in a function, when you want to trigger it
|
||||||
@ -259,37 +276,49 @@ Coin.Sent().watch({}, '', function(error, result) {
|
|||||||
// contract)
|
// contract)
|
||||||
|
|
||||||
// C. Modifiers
|
// C. Modifiers
|
||||||
// Modifiers let you validate inputs to functions
|
// Modifiers let you validate inputs to functions such as a minimal balance or user authentication
|
||||||
// The '_' (underscore) must be included, and is an indicator that the
|
// It's similar to a guard clause in other languages
|
||||||
|
|
||||||
|
// The '_' (underscore) must be included as the last line in the function body, and is an indicator that the
|
||||||
// function being called should be placed there
|
// function being called should be placed there
|
||||||
modifier onlyBefore(uint _time) { if (now >= _time) throw; _ }
|
modifier onlyBefore(uint _time) { if (now >= _time) throw; _ }
|
||||||
|
|
||||||
// You can then append it right after the function declaration
|
// You can then append it right after the function declaration
|
||||||
function test()
|
function changeOwner(newOwner)
|
||||||
onlyBefore()
|
onlyBefore(someTime)
|
||||||
{
|
{
|
||||||
|
owner = newOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. BRANCHING AND LOOPS
|
// 5. BRANCHING AND LOOPS
|
||||||
|
|
||||||
// All basic logic blocks work - including if/else, for, while, break, continue, return
|
// All basic logic blocks work - including if/else, for, while, break, continue, return
|
||||||
// switch is not provided
|
// switch is not provided
|
||||||
|
|
||||||
// Syntax is the same as javascript, but there is no type conversion from
|
// Syntax is the same as javascript, but there is no type conversion from
|
||||||
// non-boolean to boolean
|
// non-boolean to boolean, so comparison operators must be used to get the boolean value
|
||||||
|
|
||||||
// 6. CALLING AN EXTERNAL CONTRACT
|
// 6. OBJECTS/CONTRACTS
|
||||||
|
|
||||||
|
// A. Calling an external contract
|
||||||
contract infoFeed {
|
contract infoFeed {
|
||||||
function info() returns (uint ret) { return 42; }
|
function info() returns (uint ret) { return 42; }
|
||||||
}
|
}
|
||||||
|
|
||||||
contract Consumer {
|
contract Consumer {
|
||||||
InfoFeed feed; // create a variable that will point to a contract on the blockchain
|
InfoFeed feed; // create a variable that will point to a contract on the blockchain
|
||||||
|
|
||||||
|
// Set feed to an existing contract
|
||||||
function setFeed(address addr) {
|
function setFeed(address addr) {
|
||||||
// Link to the contract by creating on the address
|
// Link to the contract by creating on the address
|
||||||
feed = InfoFeed(addr);
|
feed = InfoFeed(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set feed based to a new instance of the contract
|
||||||
|
function createNewFeed() {
|
||||||
|
feed = new InfoFeed();
|
||||||
|
}
|
||||||
|
|
||||||
function callFeed() {
|
function callFeed() {
|
||||||
// T final parentheses call the contract, optionally adding
|
// T final parentheses call the contract, optionally adding
|
||||||
// custom value or gas numbers
|
// custom value or gas numbers
|
||||||
@ -297,6 +326,30 @@ contract Consumer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// B. Inheritance
|
||||||
|
|
||||||
|
// Order matters, last inherited contract (i.e., 'def') can override parts of the previously
|
||||||
|
// inherited contracts
|
||||||
|
contact MyContract is abc, def("a custom argument to def") {
|
||||||
|
|
||||||
|
// Override function
|
||||||
|
|
||||||
|
function z() {
|
||||||
|
if (msg.sender == owner) {
|
||||||
|
def.z(); // call overridden function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// C. Import
|
||||||
|
|
||||||
|
import "filename";
|
||||||
|
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
|
||||||
|
|
||||||
|
// Importing is under active development and will change
|
||||||
|
// Importing cannot currently be done at the command line
|
||||||
|
|
||||||
// 7. CONTRACT DESIGN PATTERNS
|
// 7. CONTRACT DESIGN PATTERNS
|
||||||
|
|
||||||
// A. Obfuscation
|
// A. Obfuscation
|
||||||
@ -317,6 +370,13 @@ if (!addr.send(123)) {
|
|||||||
// Suicide
|
// Suicide
|
||||||
suicide(SOME_ADDRESS); // suicide the current contract, sending funds to the address (often the creator)
|
suicide(SOME_ADDRESS); // suicide the current contract, sending funds to the address (often the creator)
|
||||||
|
|
||||||
|
// This is a common pattern that lets the owner end the contract
|
||||||
|
function remove() {
|
||||||
|
if(msg.sender == owner) { // Only let the contract creator do this
|
||||||
|
suicide(owner); // suicide makes this contract inactive, and returns funds to the owner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// D. Storage optimization
|
// D. Storage optimization
|
||||||
// Reading and writing can be expensive, as data needs to be stored in the
|
// Reading and writing can be expensive, as data needs to be stored in the
|
||||||
// blockchain forever - this encourages smart ways to use memory (eventually,
|
// blockchain forever - this encourages smart ways to use memory (eventually,
|
||||||
@ -324,19 +384,20 @@ suicide(SOME_ADDRESS); // suicide the current contract, sending funds to the add
|
|||||||
// planning your data structures)
|
// planning your data structures)
|
||||||
|
|
||||||
// *** EXAMPLE: Let's do a more complex example ***
|
// *** EXAMPLE: Let's do a more complex example ***
|
||||||
|
|
||||||
|
// ** START EXAMPLE **
|
||||||
// [TODO: Decide what a more complex example looks like, needs a few characteristics:
|
// [TODO: Decide what a more complex example looks like, needs a few characteristics:
|
||||||
// - has a 'constant' state variable
|
// - has a 'constant' state variable
|
||||||
// - has a state machine (uses modifier)
|
// - has a state machine (and uses modifier)
|
||||||
// - sends money to an address
|
// - sends money to an address
|
||||||
// - gets information from another contract (we'll show code for both contracts)
|
// - gets information from another contract (we'll show code for both contracts)
|
||||||
// - Shows inheritance
|
// - Shows inheritance
|
||||||
// - show variables being passed in on instantiation (and guard code to throw if variables not provided)
|
// - show variables being passed in on instantiation (and guard code to throw if variables not provided)
|
||||||
// - Shows the swapping out of a contract
|
// - Shows the swapping out of a contract address
|
||||||
// Ideas:
|
// Ideas:
|
||||||
// - crowdfunding?
|
// - crowdfunding?
|
||||||
// - Peer to peer insurance
|
// - Peer to peer insurance
|
||||||
// ]
|
// ]
|
||||||
|
|
||||||
// *** END EXAMPLE ***
|
// *** END EXAMPLE ***
|
||||||
|
|
||||||
// Some final points
|
// Some final points
|
||||||
@ -366,21 +427,21 @@ sha3("ab", "cd");
|
|||||||
ripemd160("abc");
|
ripemd160("abc");
|
||||||
sha256("def");
|
sha256("def");
|
||||||
|
|
||||||
// These are natspec comments, when a user is asked to confirm a transaction
|
// 8. COMMON MISTAKES/MISCONCEPTIONS
|
||||||
///
|
// A few common mistakes and misconceptions:
|
||||||
/** */
|
|
||||||
|
|
||||||
// 8. COMMON MISTAKES
|
// A. You cannot restrict a human or computer from reading the content of
|
||||||
// A few common mistakes
|
|
||||||
// You cannot restrict a human or computer from reading the content of
|
|
||||||
// your transaction or a transaction's state
|
// your transaction or a transaction's state
|
||||||
|
|
||||||
// All data to the start of time is stored in the blockchain, so you and
|
// All data to the start of time is stored in the blockchain, so you and
|
||||||
// anyone can observe all previous data states
|
// anyone can observe all previous data stats
|
||||||
|
|
||||||
// 9. TESTING
|
// When you don't specify public on a variable, you are indicating that other *contracts* can't
|
||||||
|
// read the data - but any person can still read the data
|
||||||
|
|
||||||
// 10. STYLE NOTES
|
// TODO
|
||||||
|
|
||||||
|
// 9. STYLE NOTES
|
||||||
// Use 4 spaces for indentation
|
// Use 4 spaces for indentation
|
||||||
// (Python's PEP8 is used as the baseline style guide, including its general philosophy)
|
// (Python's PEP8 is used as the baseline style guide, including its general philosophy)
|
||||||
```
|
```
|
||||||
@ -391,4 +452,7 @@ sha256("def");
|
|||||||
- [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/)
|
- [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/)
|
||||||
- [Gitter Chat room](https://gitter.im/ethereum/go-ethereum)
|
- [Gitter Chat room](https://gitter.im/ethereum/go-ethereum)
|
||||||
|
|
||||||
|
## Information purposefully excluded
|
||||||
|
- Libraries
|
||||||
|
|
||||||
Feel free to send a pull request with any edits - or email nemild -/at-/ gmail
|
Feel free to send a pull request with any edits - or email nemild -/at-/ gmail
|
Loading…
Reference in New Issue
Block a user