Suppose, we have an election contract that selects a candidate, based on highest votes, among a set of candidates. This contract can be expected to check if a voter tries to vote more than once.

An implementation of such a check should ideally respond with an error message should the check fail. In the API development world, a JSON message for the error encountered would be the way to go. However, if the same approach was used for a contract, I would imagine that, a fair share of expense would be on building and returning that JSON object.

Another option could be to return a simple JSON object in case of success as {'r' : '0x00', 'resp' : { ... } } and failure as {'r' :0x01}. A wrapper around a web3.js implementation could translate the 0x01 into something more verbose.

Other thoughts?

2 Answers 2


You need to get rid of the client-server application design model. With Ethereum you develop ÐApps, decentralized applications. Essentially, you don't need a server to tell you if you can or can't vote, you don't need to wrap web3.js neither. You already know all information you need by reading the contract on your node.

If you need more details especially about a voting contract, you can follow the official tutorial for the creation of a DAO and a liquid democracy. It show also how to interact with the contract using Mist, that is actually a commodity browser to run ÐApps.


@Guiseppe has a point about the different paradigm.

Smart contracts generally can't be amended. The immutability of contracts is a source of trust. If the logic is subject to change this would diminish trust in the system.

This leads to extremely high quality-assurance requirements. A first defense against defects in the system is to minimize complexity. Contracts are to safeguard the integrity of the application or the integrity of the voting in this case and that is enough. Complex systems of trapping errors and explaining failures push against the ideal of minimalist design.

It's a best practice to fail early and fail hard.

function castVote(args) public ... {

It can be helpful to expose the logic so clients can check:

function isAllowed(address voter) public view returns(bool isIndeed) {
  return <expression>;

This hard-line pattern of failing without explanation is the starting point. More recent editions of Solidity have added a reason. This can be added to contracts with minimal increase in complexity.

require(isAllowed(msg.sender), "The voter is not allowed.");

While this reason can be easily incorporated into contracts it is not (yet) convenient to inspect it client-side.

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.