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"