Build a message queue smart contract on EOS

We’ll start with the scenario where Alice and Bob both have access to the private key and Alice wants to send sensitive data to Bob, and leverage pyUmbral which is NuCypher’s reference implementation of Umbral (split-key threshold proxy re-encryption).

Let’s first build a message queue smart contract on EOS.

It construct one table called messages, which contains uint64_t msg_id, account_name from, account_name to, string ciphertext, and string capsule. msg_id is the primary key.

It provides two actions: sendmsg and deletemsgsendmsg requires account_name from and to, msg_id, ciphertext and capsule. Ciphertext is the encrypted message and capsule is the concept in Umbral, which is generated using pyUmbral. deletemsgbasically takes a msg_id, verifies the given toaccount_name, then deletes the record.

class queue: public eosio::contract {
    public:
        using contract::contract;
        //@abi action
        void sendmsg( account_name from, account_name to, uint64_t msg_id, const std::string & ciphertext, const std::string & capsule) {
            require_auth( from );
            messages_index messages( _self, _self );
            auto itr = messages.find(msg_id);
            if (itr != messages.end()) {
                std::string error = "msg_id already exists: " + std::to_string(msg_id);
                eosio_assert(false, error.c_str());
            }
            messages.emplace( from, [&](auto& msg){
                msg.msg_id = msg_id;
                msg.from = from;
                msg.to = to; 
                msg.ciphertext = ciphertext;
                msg.capsule = capsule;
            });
        }
        // @abi action
        void deletemsg( account_name to, uint64_t msg_id) {
            require_auth( to );
            messages_index messages(_self, _self);
            auto itr = messages.find(msg_id);
            if ( itr == messages.end() ) {
                std::string error = "msg_id does not exist: " + std::to_string(msg_id);
                eosio_assert(false, error.c_str());
            }
            
            if ( itr->to != to ) {
                std::string error = "Receipient not correct: " + eosio::name{itr->to}.to_string();
                eosio_assert( false, error.c_str());
            }
          
            messages.erase(itr);
         }
    private:
        //@abi table messages i64
        struct messages {
            uint64_t msg_id;
            account_name from;
            account_name to;
            std::string ciphertext;
            std::string capsule;
            uint64_t primary_key() const { return msg_id;}
        };
        
        typedef eosio::multi_index<N(messages), messages> messages_index;
};
EOSIO_ABI( queue, (sendmsg)(deletemsg) )

 

Compile it:

eosiocpp -o queue.wast queue.cpp
eosiocpp -g queue.abi queue.cpp
Close Menu