DIscussion - 10 hours
Professor Michael G. Solomon
BLCN 631 – Blockchain Implementation
EFD Chapter 8(b) – Learning About Solidity
Syntax – Solidity’s Grammar
This isn’t a development course
• Awareness of smart contract source code • Understanding of deployment process • Ability to interact with smart contract
functions
However, implementations require
• High-level • Just the facts
Language coverage
Basic Smart
Contract Syntax
Pragma
• Specifies which compiler versions should work
• Keeps compiler upgrades from breaking code
Comments
• Used to document code
Import
• External files your smart contract can use
Contract(s)
• Body of smart contract code
Example
pragma solidity ^0.5.0; // This is a single line comment
import library.sol; // Imports a library of functions we can use
contract HelloWorld {
string private helloMessage = "Hello world";
function getHelloMessage() public view returns (string memory) {
return helloMessage;
}
}
Storing Data in Solidity
Location Description
Stack Small local variables
Memory Local variables (default) and function arguments
Storage State variables and structs (by default)
Data Types
• uInt
• int
• byte
• string
• bool
• address
• mapping
• enum
Data Types Example pragma solidity ^0.5.0;
contract DataTypes {
uint x = 9;
int i = -68;
uint8 j = 17;
bool isEthereumCool = true;
address owner = msg.sender; // msg.sender is the Ethereum address of the account that sent this transaction
bytes32 bMsg = "hello";
string sMsg = "hello";
function getStateVariables() public view returns (uint, int, uint, bool, address, bytes32, string memory) {
return (x, i, j, isEthereumCool, owner, bMsg, sMsg);
}
}
Deploy New Contract
• Add DataTypes.sol contract to migrations var HelloWorld = artifacts.require("HelloWorld");
var DataTypes = artifacts.require("DataTypes"); // Add this line
module.exports = function(deployer) {
deployer.deploy(HelloWorld);
deployer.deploy(DataTypes); // Add this line
};
• Deploy contracts (all) truffle deploy –reset (in Truffle console)
• Invoke function (to display state variables) DataTypes.deployed().then(function(instance) {return instance.getStateVariables() });
Computation and Gas
All EVMs run all smart contract code
Denial of Service (DoS) attack
Could disable all nodes
Gas avoids DoS attacks and infinite loops
Every transaction costs some gas
More work = more gas
Incentive to keep things simple
Ethereum Gas Charges Component Comments
Gas price
Highest price per gas unit a transaction originator is willing to pay. Miners use this limit to determine if the transaction is worth including in a block. If the value is too low, the transaction may not be profitable. If too many transactions are selected with very high gas prices. It may take too long to mine the block and the miner might lose to another node.
Gas limit
Total number of gas units the transaction originator is willing to pay. It must be high enough to allow all operations to complete. If this value is too low, the EVM will terminate the transaction and undo all of its operations. Also, each block has a gas limit, so miners can’t just pick the transactions with very high gas limits - they have to choose transactions with gas limits that are cumulatively lower than the block gas limit.
Gas cost Cost of a single operation. For example, the ADD operation costs 3 gas and the MUL operation costs 5 gas.
Transaction fee Total fee for computations in a transaction. The formula is: transaction fee = total gas cost * gas price.
Unused gas If the gas limit for a transaction is greater than the actual gas cost, the unused gas is returned to the transaction originator. You only have to pay for the gas you use.
Visibility Modes Visibility What it means for functions What is means for variables
public Anyone can call this function. Anyone can access this variable’s value.
external Only external functions can call this function.
This doesn’t apply to state variables, and only external functions can access this local variable’s value.
internal Only functions in this contract and any contract deriving from it can call this function.
Only functions in this contract and any contract deriving from it can access this variable’s value.
private Only function sin this contract can call this function. Only functions in this contract can access this variable’s value.
Execution Flow Statement What it does Example
if-else Executes a group of statements if a condition is true, and optionally executes another set of statements if the condition is false (else).
numDonuts = purchasedQty; if (numDonuts >= 12)
giveDozenPrice = true; else
giveDozenPrice = false;
while Executes a group of statements zero or more times until some condition is true (pre-test repetition structure.)
numDonuts = 1; giveDozenPrice = false; While (numDonuts < purchasedQty) {
numDonuts++; if (numDonuts >= 12)
giveDozenPrice = false; break;
}
Execution Flow Statement What it does Example
do-while
Executes a group of statements one or more times until some condition is true (post-test repetition structure.) Note that a do-while loop always executes at least once.
numDonuts = 1;
giveDozenPrice = false;
do {
numDonuts++;
if (numDonuts >= 12)
giveDozenPrice = false;
break;
} (while numDonuts < purchasedQty);
for
Executes a group of statements zero or more times until some condition is true (pre-test repetition structure.) This differs from a while loop in that the test condition is modification is defined in the statement.
giveDozenPrice = false;
for (numDonuts=1; numDonuts<=purchasedDonuts; numDonuts++) {
if (numDonuts >= 12)
giveDozenPrice = true;
break;
}
Errors and Exceptions Function What it does Example
revert()
Undoes all state changes, allows a return value, and refunds remaining gas to the caller. You should use this function to catch expected conditions that indicate that a transaction should be terminated.
if (msg.sender != owner( { revert(); }
assert()
Undoes all state changes and uses up all remaining gas (i.e. does not return unused gas - like the legacy throw() function). You should never encounter this function in properly functioning code.
assert(msg.sender == owner);
require()
Undoes all state changes, allows a return value, and refunds remaining gas to the caller. You should use this function to proactively execute code when pre-requisite conditions have not been met.
require(msg.sender == owner);
Summary
HANDLING DATA IN SOLIDITY
CARRYING OUT COMPUTATIONS
IN SOLIDITY
CODING TO LIMIT GAS COST
CONTROLLING EXECUTION FLOW
RESPONDING TO ERRORS