A proof-of-concept business rules engine for the Ethereum platform that is inherently metadata-driven, written into the form of a smart contract using the Solidity language. Basically, after providing a number of rules and populating a record, a user can submit the populated record for validation by the rules engine.
- Basic knowledge of Ethereum and some experience with Javascript
- An installation of Truffle and a local blockchain (like Ganache)
- A fair amount of patience and forgiveness
This prototype only serves as an example, and it should not even be considered an attempt at an actual implementation, since it has a number of shortcomings. For example, in terms of gas usage, this contract can be somewhat expensive.
After installing the Truffle framework and configuring/starting your local blockchain, change directory to the EthgineLite repo and compile the contracts:
$ truffle compile
Then deploy them to your local blockchain
$ truffle migrate
And finally test the engine using the provided Javascript file:
$ truffle test
1.) First, you need to define the data point(s) that we will want to test with the rules engine (like a Price, for example).
// INSIDE THE CONTRACT'S CONSTRUCTOR
attributes.push(WonkaLib.WonkaAttr({
attrId: 2,
attrName: "Price",
maxLength: 128,
maxLengthTruncate: false,
maxNumValue: 1000000,
defaultValue: "000",
isString: false,
isDecimal: false,
isNumeric: true,
isValue: true
}));
// INSIDE THE TEST SCRIPT
instance.addAttribute(web3.fromAscii('Language'), 64, 0, new String('ENG').valueOf(), true, false);
For now, the engine automatically creates three Attributes in the engine's constructor, but that could be changed easily.
2.) Next, you need to create a RuleSet for containing the rules:
instance.addRuleSet(accounts[0], web3.fromAscii('ValidateProduct'));
As well as create the Rule itself:
instance.addRule(accounts[0], web3.fromAscii('Validate price'), web3.fromAscii('Price'), GREATER_THAN_RULE, new String('0099').valueOf()); // in cents, since we can't use decimals
3.) Then, we need to populate our record (held within the contract instance for us) with the data:
// SINCE ETHEREUM HAS LIMITATIONS WHEN DEALING WITH DYNAMIC ARRAYS AND MAPPINGS, WE MUST KEEP AN ARRAY/MAPPING
// ON THE CONTRACT SIDE AND MANIPULATE IT FROM THE CLIENT
instance.setValueOnRecord(accounts[0], web3.fromAscii('Title'), new String('The First Book').valueOf());
instance.setValueOnRecord(accounts[0], web3.fromAscii('Price'), new String('0999').valueOf()); // in cents
instance.setValueOnRecord(accounts[0], web3.fromAscii('PageAmount'), new String('289').valueOf());
4.) Finally, we execute the rules engine, using our provided RuleSet and applying it to our specified data record:
instance.execute.call(accounts[0]);
And we learn whether or not the data record is valid, according to our provided rules.
This project will no longer be developed any further, since it only served as a proof of concept. However, you can understand its basis by reading about the ideas and the general design presented in my InfoQ article that talks about metadata-driven design (i.e., MDD) and business rules.