BitShares founder: Lisk smart contracts are not smart, far inferior to Ethereum

BitShares founder: Lisk smart contracts are not smart, far inferior to Ethereum

Lisk smart contracts are not that smart. As a blockchain developer, I was excited when I read the marketing materials of Lisk. The concept of a blockchain and smart contract platform driven entirely by JavaScript is something I have always wanted to build. I have never done it because the complexity involved is beyond my ability to bear in terms of time and budget.

(Photo: Daniel Larimer, founder of BitShares)

Purpose of Smart Contract Platform

Developing blockchain technology is challenging because you need to ensure that your software behaves in a deterministic manner and that it can recover from any errors without leaving any unwanted side effects. Sometimes something as simple as mathematical operations using floating point numbers can lead to non-deterministic behavior and bring losses.

When designing a smart contract platform, I look forward to providing developers with the following tools:

  1. Automatic rollback in case of error;

  2. Cannot generate non-deterministic code;

  3. The ability to prevent infinite loops or measure total computation;

  4. The ability to prevent unbounded memory growth or measure memory consumption;

I was struck by the fact that Lisk did not solve any of the problems listed above. Their "sandbox" cannot be used to run untrusted code, their theoretical framework does not provide any protection against non-deterministic behavior, there is no way to measure or limit resource usage, and they do not even provide tools to ensure that errors can be properly rolled back.

How bad is the situation?

I decided to check out some of Lisk's example "apps", and the first example is a simple messaging app. The purpose of this app is to allow people to send messages to each other via the blockchain. As a Lisk developer, I would want to do the following:

  1. Define messages and perform serialization operations;

  2. Manually process requests and undo changes to the database;

  3. Manually resolve changes to blockchain balances;

  4. Manually handle "confirmed" and "unconfirmed" status;

As you can see here, Lisk offers almost no help to developers. In fact, the API it provides to developers is overly complex and reminds me of the early BitShares 1.0 framework. In BitShares 1.0, we found that it slowed down the development of the project and was incredibly error-prone.

Lisk vs Non-Smart Contract Platforms

I recently implemented a similar messaging app (aka plugin) for Steem, which isn’t even a smart contract platform! My messaging plugin is a bit more powerful and complex than the Lisk one. So, I’ll show a simplified version below. Don’t worry if you can’t read the code, just read the explanation.

Step 1 – Define the message

 struct private_message {
string from;
string to;
string message;
};
FC_REFLECT( private_message, (from)(to)(message) )

Step 2 - Define a database and index

This step is no more complex than using standard Boost Multi Index Containers. These containers perform better than any SQL database with similar indexes. In this case, we build a powerful index that makes it easy to request messages in the order they were received or sent. This enables the "Inbox" and "Outbox" functionality for every user.

 struct message_object {
time_point received;
string from;
string to;
string message;
};
FC_REFLECT_DERIVED ( message_object, (db::object), (received)(from)(to)(message) )

struct by_to_date;
struct by_from_date;
struct by_id;
typedef multi_index_container<
message_object,
indexed_by<
ordered_unique< tag< by_id >, member< object, object_id_type, &object::id > >,
ordered_unique< tag< by_to_date >,
composite_key< message_object,
member< message_object, string, &message_object::to >,
member< message_object, time_point, &message_object::receive_time >,
member<object, object_id_type, &object::id >
>,
composite_key_compare< less,
greater< time_point >,
less< object_id_type > >
>,
ordered_unique< tag< by_from_date >,
composite_key< message_object,
member< message_object, string, &message_object::from >,
member< message_object, time_point, &message_object::receive_time >,
member<object, object_id_type, &object::id >
>,
composite_key_compare< less,
greater< time_point >,
less< object_id_type > >
>
>
> message_multi_index_type;

typedef generic_index< message_object, message_multi_index_type> private_message_index;

Step 3 - Define an API

Define an API whose purpose is to allow third parties to check the status of your application. In this example, we need two API calls, one for the inbox and the other for the outbox.

 class private_message_api : public std::enable_shared_from_this<private_message_api> {
public:
typedef vector<message_object> messages;
private_message_api(const app::api_context& ctx):_app(&ctx.app){}

messages get_inbox( string to, time_point newest, uint16_t limit )const;
messages get_outbox( string from, time_point newest, uint16_t limit )const;
private:
app::application* _app = nullptr;
};

Step 4 - Implement the message handler

The purpose of this method is to update the state when each private_message operation is included in the blockchain. The message handler is responsible for verifying that the message is signed by the sender, and if so, adding the message to the database.

 void private_message_plugin::on_operation( const operation_object& op_obj ) {
if( op_obj.op.which() == operation::tag<custom_json_operation>::value ) {
const custom_json_operation& cop = op_obj.op.get<custom_json_operation>();
if( cop.id == "private_message" ) {
auto message = json::from_string(cop.json).as<private_message_operation>();
FC_ASSERT( cop.requires_auth(message.from),"sender didn't sign message" );

db.create<message_object>( [&]( message_object& pmo ) {
pmo.from = pm.from;
pmo.to = pm.to;
pmo.message = pm.message;
pmo.receive_time = db.head_block_time();
});
}
}
}

Step 5 - Implementing the API

This API is accessible to the steemd process via JSON RPC. The get_outbox API is almost identical except that it uses the alternative directive by_from_date instead of by_to_date .

 messages private_message_api::get_inbox( string to,
time_point newest,
uint16_t limit )const
{
const auto& pmi = db.get_index_type<private_message_index>();
const auto& idx = pmi.indices().get<by_to_date>();

messages result;
auto itr = idx.lower_bound( make_tuple( to, newest ) );
while( itr != idx.end() && limit && itr->to == to ) {
result.push_back(*itr);
++itr; --limit;
}

return result;
}

Comparison between Steem and Lisk

For this particular information application, Steem’s example is much more robust and concise than the one given by Lisk. Especially when you note the following:

  1. The app developers did not implement any undo functionality.

  2. App developers don't have to worry about costs.

  3. Application developers don't have to worry about the difference between confirmed and unconfirmed.

  4. Application developers do not have to worry about serialization issues.

  5. The code can be shorter.

While the Steem blockchain automatically handles these complexities, developers must also be careful that their implementation does not create an infinite loop, memory leaks, or produce nondeterministic behavior. Fortunately, C++ is much easier to develop when deterministic behavior is required. Using many common JavaScript language features results in nondeterministic behavior being hidden.

Lisk Sidechain

One of Lisk’s smart contract concepts is the use of sidechains. Lisk smart contracts cannot hold funds because validating nodes do not execute the code. Lisk relies on a third-party multi-signature solution to evaluate the code and authorize transactions.

Using STEEM and BitShares, developers can implement smart contracts in the same way. The main difference is that C++ is used instead of JavaScript. Steem has a major advantage that other smart contract platforms do not have: free transactions. This means that anyone can implement a sidechain "smart contract plugin" without having to worry about the fees required by the contract.

Ethereum is more advanced

I have raised many issues with Ethereum in the past, but compared to Lisk, I think Ethereum is a developer's paradise. Ethereum helps developers solve many problems that have plagued many experienced blockchain developers. Mastering the syntax of a new language is trivial compared to learning millions of ways to avoid shooting yourself in the foot. Ethereum applications do not produce non-deterministic behavior.

Moving Forward

Blockchain technology is constantly moving forward, and the Lisk team has just raised a large sum of money to advance the platform. Most of the problems faced by Lisk can be solved with a highly customized JavaScript environment.

Currently, the gap between Lisk and its goal is huge. If they can solve the problems I have raised, then one day their platform will be able to provide some competition to Ethereum. For starters, Lisk's architecture will scale better than Ethereum, and using JavaScript is a major advantage. To develop Lisk from its current state into a true competitor to Ethereum will probably consume all the money raised by the group, or even more.

in conclusion

If you consider Lisk to be a smart contract platform powered by the JavaScript language, then you should consider STEEM to be a serious competitor with more capabilities than Lisk currently has. If you do not consider Steem to be a general purpose smart contract platform, then it is clear that Ethereum is still the only game in town.


<<:  "Blockchain: Reshaping the Economy and the World" takes you into the application scenarios of blockchain

>>:  Gavin Anderson: Ethereum’s rise should serve as a warning to Bitcoin

Recommend

How to distinguish between true and false palm breaks

Although the broken palm line is not particularly...

What does the broken palm lines on both hands mean?

In palmistry, each line on the palm has a differe...

Are women without earlobes necessarily unlucky?

If a woman has no earlobes, does that mean she ba...

Moles that indicate men are prone to cheating

Moles are one of the facial features that many pe...

What kind of man can I marry?

For women, getting married is a major event that ...

The woman behind the successful man

The woman behind the successful man Behind every ...

The face of a woman who would never marry far away

There are many times when there is a certain conf...

A woman has a mole on her left eyebrow

Although small moles may seem insignificant, they...