Solidity Notes
Solidity has basic structure like so
Contracts
contract NewContract {
uint data; // contract fields like this are in storage
constructor(uint _data) public {
uint[] memory memoryLocalArray; //in memory storage
data = _data
}
}
Memory
-
storage
- persisted state
- key value store (256 bit)
- read and write are costly
- contract can manage only it's own
-
memory
- temporary
- arrays and structs
- addressable at byte level
-
callData
- evm code execution
- non modifiable
- max size 1024, word 256 bit
Data Types
Solidity has elementary and complex data types.
Elementary Data Types
- uint - use for unsigned integers of various sizes (+ only)
- defaults to
0
- defaults to
- int - for signed integers of various sizes ( +/- )
- defaults to
0
- defaults to
- bool - true/false
- defaults to
false
- defaults to
- address - address of externally owned account or contract account. Holds a 20 byte hex string of an Ethereum address. It is a Value Type.
- uninitialized address =
0x0
- uninitialized address =
default is a 32 bit for uint
and int
https://en.wikipedia.org/wiki/32-bit_computing
uint8 variables can only hold upto a byte, which means numbers from 0-255, but a 32 bit unsigned is 4,294,967,295 (232 − 1)
https://docs.soliditylang.org/en/v0.5.0/types.html?highlight=memory
Conversions Type
-
implicit conversion
-
uint a = 255
works -
uint b = 256
compilation error -
uint8 a = 255; uint c = a;
works -
explicit conversion
-
uint loss = 260; uint8 small = uint8(loss);
leads to data loss
Complex Data Types
-
arrays *fixed size array
// Solidity program to demonstrate // creating a fixed-size array pragma solidity ^0.5.0; // Creating a contract contract Types { // Declaring state variables // of type array uint[6] data1; // Defining function to add // values to an array function array_example() public returns ( int[5] memory, uint[6] memory){ int[5] memory data = [int(50), -63, 77, -28, 90]; data1 = [uint(10), 20, 30, 40, 50, 60]; return (data, data1); } }
- Dynamic Array
// Solidity program to demonstrate // creating a dynamic array pragma solidity ^0.5.0; // Creating a contract contract Types { // Declaring state variable // of type array. One is fixed-size // and the other is dynamic array uint[] data = [10, 20, 30, 40, 50]; int[] data1; // Defining function to // assign values to dynamic array function dynamic_array() public returns( uint[] memory, int[] memory){ data1 = [int(-60), 70, -80, 90, -100, -120, 140]; return (data, data1); } }
-
struct
-
cannot have member of it's own type
-
can be contained in arrays/mappings
pragma solidity >=0.4.24;
contract StructsContract {
// Family
struct Family {
bytes32 lastName;
uint8 houseNo;
uint16 age;
}
// Creating an array of type family..which is a struct
Family[] myFamily;
// Getting a lastName, and returning complete
// family details
// We cannot compare 2 strings in solidity...
function getName(bytes32 name) public view returns (bytes32, uint8, uint16) {
// Search the array
for(uint8 i = 0; i < myFamily.length; i++){
if(name == myFamily[i].lastName) {
return (myFamily[i].lastName,uint8(myFamily[i].houseNo), myFamily[i].age);
}
}
}
// Structs Cannot be passed as argument so we are passing all elements/attributes of struct as args
function addName(bytes32 _lastName, uint8 _value, uint16 _age) public returns (bool) {
// Declare the struct variable in memory...
Family memory newFamily;
// use the . notation to access members of a struct
newFamily.lastName = _lastName;
newFamily.houseNo = _value;
newFamily.age = _age;
// Push the newFamily struct...into our myFamily array
myFamily.push(newFamily);
return true;
}
}
- not part of abi, external calls cannot send or recieve the struct type, however calls internal can
- mapping
- hash is stored as the value of the key
- allowed only as storage or state variable, cannot be local to a function
- key can be anything except another mapping
- value type can be another mapping
- not iterable - no
.length
property - value exists for all keys
0x0
if no value was provided, - missing key returns
null|undefined
pragma solidity >=0.4.24;
contract MappingsContract { // Creates in Storage mapping(string => string) relations;
// Add a relation
function addRelation(string memory name, string memory relation) public {
// Store the relation
relations[name] = relation;
}
// Returns a Relation
function getRelation(string memory name) public view returns (string memory){
return relations[name];
}
// Remove the key value pair from the mapping
function removeRelation(string memory name) public {
delete(relations[name]);
}
}
* string
https://docs.soliditylang.org/en/v0.5.3/types.html?highlight=string#string-literals-and-types
dynamic byte array is the data type of a string
* bytes
https://docs.soliditylang.org/en/v0.5.3/types.html?highlight=string#fixed-size-byte-arrays
https://docs.soliditylang.org/en/v0.5.3/types.html?highlight=string#dynamically-sized-byte-array
Example of convert string to bytes and getting index of string in byte
pragma solidity >=0.4.22 <0.9.0;
contract StringConversion {
function getStringElementAtIndex(uint index, string memory myString) public pure returns (byte){
bytes memory stringToBytes = bytes(myString);
return stringToBytes[index];
}
}
* enums
* https://docs.soliditylang.org/en/v0.5.3/types.html#enums
* indexed values
enum TransferType {Domestic, Foreign} //No semicolon //will not be part of ABI definition //explicit conversion to/from integer type uint8 transferTypeInt = TransferType.Domestic //compile error uint8 transfertTypeInt = uint8(TransferType.Domestic);//compiles
another example enum contract
pragma solidity >=0.4.24;
contract EnumsContract {
// Create an Enumeration
enum names {Joe, Brandy, Rachna, Jessica}
// get the value at specified index
function getNames(uint8 arg) public pure returns (string memory){
if(arg == uint8(names.Joe)) return "Joe";
if(arg == uint8(names.Brandy)) return "Brandy";
if(arg == uint8(names.Rachna)) return "Rachna";
if(arg == uint8(names.Jessica)) return "Jessica";
}
}