Advanced ENI Useage

This example shows how to use our eni_strsplit.so to spilt a string on Lity contract.

Eni library - StrSplit

Here is sample code for eni_strsplit.so

#include <eni.h>

class StrSplit : public eni::EniBase
{
public:
  StrSplit(const std::string& pArgStr) : eni::EniBase(pArgStr) { }

  ~StrSplit() { }

private:
  bool parse(const json::Array& pArgs) override {
    m_Base = pArgs[0].toString();
    m_Target = pArgs[1].toString();
    m_Offset = static_cast<std::size_t>(pArgs[2].toInteger());
    return true;
  }

  eni::Gas gas() const override {
    return m_Base.length() * 10;
  }

  bool run(json::Array& pRetVal) override {
    std::size_t pos = m_Base.find(m_Target, m_Offset);
    std::string ret = m_Base.substr(m_Offset, pos - m_Offset);
    pRetVal.emplace_back(ret);
    return true;
  }

private:
  std::size_t m_Offset;
  std::string m_Base;
  std::string m_Target;
};

ENI_C_INTERFACE(strsplit, StrSplit)

Compiler StringSplit Contract

There is a simple contract that leverage ENI to split a string.

pragma lity ^1.2.6;

library StringUtil
{
    struct Splitter {
        string base;
        string cut;
        uint offset;
    }

    function warp(string memory str) internal pure returns(string memory)
    {
        return str;
    }

    function get(Splitter memory self) internal pure returns(string memory)
    {
      string memory res = eni("strfind", self.base, warp(self.cut), self.offset);
      self.offset += bytes(res).length + bytes(self.cut).length;
      return res;
    }
}

contract A
{
  using StringUtil for *;
  function main(string memory dat) public pure returns(string memory)
  {
    StringUtil.Splitter memory sp = StringUtil.Splitter(dat,"|",1);
    return sp.get();
  }
}

and we could compile it using lityc:

$ mkdir output
$ lityc --abi --bin -o output StringSplit.sol
$ cat output/StringSplit.abi
[{"constant":true,"inputs":[{"name":"dat","type":"string"}],"name":"main","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]
$ cat output/StringSplit.bin
608060405234801561001057600080fd5b50610372806100206000396000f3fe608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063769f204d14610046575b600080fd5b34801561005257600080fd5b5061010c6004803603602081101561006957600080fd5b810190808035906020019064010000000081111561008657600080fd5b82018360208201111561009857600080fd5b803590602001918460018302840111640100000000831117156100ba57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610187565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014c578082015181840152602081019050610131565b50505050905090810190601f1680156101795780820d805160018360200d6101000a0d1916815260200191505b509250505060405180910390f35b6060610191610324565b6060604051908101604052808481526020016040805190810160405280600181526020017f7c000000000000000000000000000000000000000000000000000000000000008152508152602001600181525090506101ee816101f6565b915050919050565b60608082600001519050606060405160206040519081016040526003905260206040519081016040527f6b6b090000000000000000000000000000000000000000000000000000000000905260206040519081016040526001905260206040519081016040527f0400000000000000000000000000000000000000000000000000000000000000905260206040519081016040528060009052836020604051908101604052526102a9866020015161031a565b602060405190810160405252856040015160206040519081016040525280604051819003602090039052907f73747266696e6400000000000000000000000000000000000000000000000000f590508360200151518151018460400181815101915081815250508092505050919050565b6060819050919050565b606060405190810160405280606081526020016060815260200160008152509056fea165627a7a72305820528470889262bcbbc0e1f4d9bb534e1f9f132ce4bdaa0b66531043d9281209440029

Deploy contract to Travis locally

After we get contract ABI and bytecode, we could deploy it to Travis chain.

# Get Travis console
travis attach http://127.0.0.1:8545

# Deploy contract (in Travis console)
personal.unlockAccount(cmt.accounts[0], '1234');
abi = [{"constant":true,"inputs":[{"name":"dat","type":"string"}],"name":"main","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]
bytecode = "0x608060405234801561001057600080fd5b50610372806100206000396000f3fe608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063769f204d14610046575b600080fd5b34801561005257600080fd5b5061010c6004803603602081101561006957600080fd5b810190808035906020019064010000000081111561008657600080fd5b82018360208201111561009857600080fd5b803590602001918460018302840111640100000000831117156100ba57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610187565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014c578082015181840152602081019050610131565b50505050905090810190601f1680156101795780820d805160018360200d6101000a0d1916815260200191505b509250505060405180910390f35b6060610191610324565b6060604051908101604052808481526020016040805190810160405280600181526020017f7c000000000000000000000000000000000000000000000000000000000000008152508152602001600181525090506101ee816101f6565b915050919050565b60608082600001519050606060405160206040519081016040526003905260206040519081016040527f6b6b090000000000000000000000000000000000000000000000000000000000905260206040519081016040526001905260206040519081016040527f0400000000000000000000000000000000000000000000000000000000000000905260206040519081016040528060009052836020604051908101604052526102a9866020015161031a565b602060405190810160405252856040015160206040519081016040525280604051819003602090039052907f73747266696e6400000000000000000000000000000000000000000000000000f590508360200151518151018460400181815101915081815250508092505050919050565b6060819050919050565b606060405190810160405280606081526020016060815260200160008152509056fea165627a7a72305820528470889262bcbbc0e1f4d9bb534e1f9f132ce4bdaa0b66531043d9281209440029"
contract = web3.cmt.contract(abi);
c = contract.new(
  {
    from: web3.cmt.accounts[0],
    data: bytecode,
    gas: "4700000"
  },
  function(e, contract) {
    console.log("contract address: " + contract.address);
    console.log("transactionHash: " + contract.transactionHash);
  }
);

Use contract to reverse a string

# Use main() function to show spilt of "aLITY|nextstr" from first char (zero-base)
> c.test.call('aLITY|nextstr);
"LITY"