...by Daniel Szego
quote
"On a long enough timeline we will all become Satoshi Nakamoto.."
Daniel Szego

Saturday, January 13, 2018

Solidity and Truffle Tips and Tricks - passing struct argument by reference


In solidity the structs given as parameters for a function are mostly given by value, meaning that the whole struct is practically duplicated in memory and handled as a local copy of the original struct. There is one exception that you can use if you want to use another semantics: with internal and private functions you can use the storage keyword to make sure that the struct us handled as reference and not as value. 

contract StructTestContract {
    
  struct TestStruct{
     uint a;
  }
    
  TestStruct public myStruct= TestStruct(1);
    
  function copyStructByValue(TestStruct _struct){
     _struct.a = 2;
  }

 function copyStructByReference(TestStruct storage _struct) internal{
     _struct.a = 2;
  }

 function testCopyStructByValue(){
    copyStructByValue(myStruct);
 }

 function testCopyStructByReference(){
    copyStructByReference(myStruct);
 }
}

In the previous example, copyStructByReference has got a real reference to the TestStruct resulting 2 after the function call, as copyStructByValue simply copies the whole struct meaning that the original value will not change. 

Solidity and Truffle Tips and Tricks - time in solidity


Time in solidity does not have too many options unfortunately, what you can use is basically an uint variable that represents a UNIX timestamp, that is basically the number of ticks or seconds since the 1th of January 1970. You can have the keywords now to represent the current timestamp and use the keywords like seconds, minutes, hours, days, weeks or years to add or subtract time elements. As it is demonstrated in the following code fragment:

    uint currentTime = now;
    uint nextSecond = currentTime + 1 seconds;
    uint nextMinute = currentTime + 1 minutes;
    uint nextHour = currentTime + 1 hours;
    uint nextDay = currentTime + 1 days;
    uint nextWeek = currentTime + 1 weeks;
    uint nextYear = currentTime + 1 years;



Solidity gas optimization - small int types and structs


If you use structs with integers smaller than the maximum available value, like int8, uint8, int32, uint32, you can have the chance that the solidity compiler optimizes the values into one storage element. Sometimes the storage is optimized even without an explicit struct, just with defining the small integers in a row. Taking the following code segment:

contract gasOptimisation{
    uint8 a;
    string test1;
    uint8 b;
    string test2;
    uint8 c;
    string test3;
    uint8 d;

  struct Integers{
     uint8 a;
     uint8 b;
     uint8 c;
     uint8 d;
  }    

 Integers ints;

  function setInt() {
    a = 1;
    b = 2;
    c = 3;
    d = 4;
  }

  function setStruct(){
     ints = Integers(1,2,3,4);
  }   
 }   

Running  setInt costs more than two times as much gas as running setStruct, because probably the compiler optimizes the four variables into one 32 byte word. However, if we remove the string declarations from the uint8 variables on the top of the contract, than setInt function and the storage of a,b,c,d variables are optimized as well, even without struct.      


Wednesday, January 10, 2018

Solidity and Truffle Tips and Tricks - setting up development environment with Parity



1. Install Parity: you can install parity on Ununtu or Linux with the following one line command:

 bash <(curl https://get.parity.io -kL)

2. Start development blockchain with Parity: for starting Parity development environment simply type start parity with the following parameters:

 --config dev or --chain dev for the development envrionment
 --force-ui for having a user interface
 --base-path set a base path as well, otherwise not really working for some reason.

by default, the local web environment as http://localhost:8180, you can create some new accounts, transfer ether from the development account to the others. It is an important information that the passphrase for the development account is simply an empty string. 

3. Configure Truffle with Parity: configure with the locally installed Parity environment in truffle.js as: 

networks: {
    parity: {
      host: "127.0.0.1",
      port: 8545,
      from: "0x00a329c0648769A73afAc7F9381E08FB43dBEA72",
      network_id: "*", // Match any network id
      gas: 4600000
    }
  }

It is a good idea to put some gas limit into the config file, as the parity gas limit configuration might not match with the default of Truffle.

4. Deploy with Truffle: migrate to the local parity network and test in the user interface under txqueue viewer if the transaction has been mined. Pay attention that truffle migration deploys more than one contract, so you have to sign the transaction on the graphical user interface more than once. 

 truffle migrate --network parity --verbose-vp

5. Test your contract with Parity


Ethereum token with adjustable crypto-monetary policy with group of addresses


As we have mentioned in our previous blog there is a possibility and sometimes the need as well to create a token that has a actually a monetary base and an extended money supply as well that can be achieved in the most easy way with the help of a simple multiplicator value. However in certain situations, there might be the need to have something as multiply multiplication.

So let we further refine our model, let be M0 the monetary basis and M1 = M0 * m is an extended monetary supply where m is a multiplication number. Let we define an M2 refined and extended monetary supply in a way that:

- let G={g1, g2, ... gn} a set of groups, in a way that
- for each A={a1, a2, ... ak} possible addresses, there is maximum one gi group in which the address is member
- let |G|={|g1|,|g2|, ... |gn|} the number of addresses that are associated to a given group
- besides, let we have for each group a {m1, m2, ... mk} multiplicator value.

If so, we can define the M2 refined extended monetary supply:

M2 = M1 * Sumi (|ai| * mi) / Sumi (|ai|)

It is practically a measure for creating an average of different multiplicator values weighted by the size of the groups.





   

Tuesday, January 9, 2018

Minimal ERC20 token with adjustable monetary policy


As we have seen in the previous blog (Ethereum token with adjustable monetary policy), there might be a good idea to design a token with adjustable monetary supply, in a way that there is actually at least two token balances an M0 basic monetary supply and an M1 that is a dynamic multiplication of the basic monetary supply. The following code demonstrates a minimal implementation of such a token. For the first run as a simple sketch, without having some necessary elements for a live system, like Transfer event, safe match functions or token information fields 

contract SimpleMonetaryToken {

 mapping(address => uint256) m0Balances;
 uint256 public monetaryMultiplicator = 110;

 uint initialSupply = 10000;

 function SimpleMonetaryToken(){
  m0Balances[msg.sender] = initialSupply;
 }

 function transfer(address _to, uint256 _m1Value) public returns
      (bool) {
  uint256 _m0Value = (_m1Value * 100) / monetaryMultiplicator;
  require(_to != address(0));
  require(_m0Value <= m0Balances[msg.sender]);

  m0Balances[msg.sender] = m0Balances[msg.sender] - _m0Value;
  m0Balances[_to] = m0Balances[_to] + _m0Value;
  return true;
  }

 function balanceOf(address _owner) public view returns (uint256
  balance) {
   return (m0Balances[_owner] * monetaryMultiplicator) / 100;
 }

Certainly, the structure should be further tested regarding the possible hackings or attacks. As an example division represents actually a rounding, so it might produces some inconsistencies or possible hackings. On the other hand, due to multiplications with 100, the overflow can be a critical issue.






Sunday, January 7, 2018

Ethereum token with adjustable crypto-monetary policy


To realize tokens with adjustable monetary policy is actually pretty much a challenge. One way of doing it is to create something like a mintable token that has an explicit function called mint that is able to create new tokens on a certain account. However this structure actually does serve well in certain use cases, like:
- if the newly generated tokens should be distributed somehow to all of the possible accounts
- if the monetary supply is not only to be increased but, we should be able to decreased as well.

In such situations, perhaps another algorithm might be feasible, that has the analogy in the classical banking systems. Let we imagine as a simple situation that we have actually two monetary basis, M0 is practically the amount of cash in the system and M1 is the amount of electronic money in the system. In the most simple situation, M1 is based on the reserve rates of the banks that is identified by the central banks, so simply put: 

M1 = m * M0, where m is a multiplication factor  

Having this structure, tokens might be built up directly that captures this functionality in a direct way:
- balance: balance as an internal mapping would always store the M0 value, however a balance function can be derived that gives the M1 value back. 
- transfer: transfer should always be regarded to the M1 value, based on the current m multiplication factor, balance M0 balance should be as M1/m adjusted. 

Certainly, it a pretty good question how such a token could work from an end-user perspective. As certainly, having more token on the balance is pretty nice to have, having less is probably not really accepted. On the other hand, people might explicitly distinguish between M0 and M1 balance, which might cause some less welcoming economic behaviors, like spending more if the m value is high, but spending less if it is low. 





Solidity and Truffle Tips and Tricks - unit tests and states


Truffle initializes new the state of the smart contracts (or deploys them new) both at the beginning of the testing and at each contract keywords. This practically means each new test starts from the state that is initialized by the migration script. From a practical point of view the following statement means a complete new initialisation or deployment:

contract('Contract', function(accounts) {
...

Solidity and Truffle Tips and Tricks - unit test from a different account


Supposing you want to carry out a unit test from a specific account that is different as the default account, you can basically use the accounts array that is initialized by the truffle development environment and you can explicitly set a specific account as accounts[i] at the function call:

contract('Contract', function(accounts) {
 it("test Contract other account", function() {
  return Contract.deployed().then(function(instance) {
   return Contract.callFunction( <parameters> {from:accounts[i]});  
   }).then( 
...
...

Solidity and Truffle Tips and Tricks - testing errors as unit tests


Supposing that you have to write a solidity unit test and you expect the result as an error message, you can use the following pattern, simply using catch in the unit testing instead of or beside then

contract('Contract', function(accounts) {
 it("test Contract from wrong account", function() {
  return Contract.deployed().then(function(instance) {
   return Contract.callFunction(<params>); 
  }).then(function(balance) {
   assert(false, "Call should not be allowed");            
  }).catch(function(error) {
   errorMessage = error.toString();
   if (errorMessage.indexOf("invalid opcode")  > 0){
    assert(true, "Call should not be allowed - error as expected");     }
    else{
   assert(true, "Call should not be allowed - wrong message");   
    }
   });
  });
});