<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>gachengoh</title>
        <link>https://paragraph.com/@gachengoh</link>
        <description>I love Blockchain technology.I believe in DeFi and I am in the process of banking the unbanked in Africa. I write about Blockchain security</description>
        <lastBuildDate>Tue, 01 Sep 2026 07:42:27 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>gachengoh</title>
            <url>https://storage.googleapis.com/papyrus_images/cd1ce8f85162b59b0451b1983c5c026464dd1bd4683ecab8931b6580d08c06c0.jpg</url>
            <link>https://paragraph.com/@gachengoh</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[MultiSig Wallet]]></title>
            <link>https://paragraph.com/@gachengoh/multisig-wallet</link>
            <guid>5VbHz8wY3MAbruHqIW1n</guid>
            <pubDate>Sun, 04 Dec 2022 19:48:05 GMT</pubDate>
            <description><![CDATA[This post is implementing a multisig wallet in solidity,where there must be a number of people to authorize transfer of funds from the wallet.// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 &#x3C;0.9.0; contract MultisigWallet { event Deposit (address indexed sender,uint amount,uint balance); event SubmitingTransaction(address indexed owner, uint indexed txIndex, address indexed to, uint value, bytes data); event ConfirmingTransaction( address indexed owner, uint indexed txIndex);...]]></description>
            <content:encoded><![CDATA[<ul><li><p>This post is implementing a multisig wallet in solidity,where there must be a number of people to authorize transfer of funds from the wallet.</p></li></ul><pre data-type="codeBlock" text="// SPDX-License-Identifier: GPL-3.0

pragma solidity &gt;=0.7.0 &lt;0.9.0;

contract MultisigWallet {

    event Deposit (address indexed sender,uint amount,uint balance);
    event SubmitingTransaction(address indexed owner, uint indexed txIndex, address indexed to, uint value, bytes data);
    event ConfirmingTransaction( address indexed owner, uint indexed txIndex);
    event RevokingConfirmation(address indexed owner, uint indexed txIndex);
    event ExecutingTransaction(address indexed owner, uint indexed txIndex);

    //State Variables.
    address[] public owners;
    mapping(address =&gt; bool) public isOwner;
    uint public numConfirmationsRequired;

    struct Transaction {
        address to;
        uint value;
        bytes data;
        bool executed;
        uint numConfirmations;
    }
    Transaction [] public transactions;

    // mapping from tx index =&gt; owner =&gt; bool
    mapping(uint =&gt; mapping(address =&gt; bool)) public isConfirmed;

    constructor(address [] memory _owners, uint _numConfirmationsRequired)  {
        require(_owners.length &gt; 0,&quot;Owners Required&quot;);
        require(_numConfirmationsRequired &gt; 0 &amp;&amp; _numConfirmationsRequired &lt;= _owners.length, &quot;Invalid number of required Confirmations&quot;);

        for (uint i = 0; i &lt; _owners.length; i++){
            address owner = _owners[i];

            require(owner != address(0), &quot;invalid Owner&quot;);
            require(!isOwner[owner], &quot;Owner is not unique&quot;);

            isOwner[owner] = true;
            owners.push(owner);
        }

        numConfirmationsRequired = _numConfirmationsRequired;
    }

    modifier onlyOwner () {
        require(isOwner[msg.sender], &quot;Not Owner&quot;);
        _;
    }
    modifier txExists(uint _txIndex) {
        require(_txIndex &lt; transactions.length, &quot;Transaction does not exist&quot;);
        _;
    }
    modifier notExecuted(uint _txIndex) {
        require(!transactions[_txIndex].executed, &quot;Transactions already executed&quot;);
        _;
    }

    modifier notconfirmed(uint _txIndex){
        require(!isConfirmed[_txIndex][msg.sender], &quot;tx already confirmed&quot;);
        _;
    }

    receive() external payable {
        emit Deposit(msg.sender, msg.value, address(this).balance);
    }

    function deposit() external payable {
        emit Deposit (msg.sender,msg.value,address(this).balance);
    }

    function submitTransaction(address _to, uint _value, bytes memory _data) public onlyOwner {

        uint txIndex = transactions.length;
        transactions.push(Transaction({
            to: _to,
            value: _value,
            data: _data,
            executed: false,
            numConfirmations: 0
        }));
        emit SubmitingTransaction(msg.sender, txIndex, _to, _value, _data);
    }
    function confirmTransaction(uint _txIndex) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) notconfirmed(_txIndex){

        Transaction storage transaction = transactions[_txIndex];
        isConfirmed[_txIndex][msg.sender] = true;
        transaction.numConfirmations += 1;

        emit ConfirmingTransaction( msg.sender, _txIndex);
    }
    function executeTransaction(uint _txIndex) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) {

        Transaction storage transaction = transactions[_txIndex];
        require(transaction.numConfirmations &gt;= numConfirmationsRequired,&quot;Cannot Execute Transaction&quot;);

        transaction.executed = true;
        (bool success,) = transaction.to.call{value: transaction.value}(transaction.data);
        require(success, &quot;tx failed&quot;);

        emit ExecutingTransaction(msg.sender, _txIndex);

    }
    function revokeConfirmation(uint _txIndex) public onlyOwner txExists(_txIndex) notExecuted(_txIndex){

        Transaction storage transaction = transactions [_txIndex];
        require(isConfirmed[_txIndex][msg.sender], &quot;Transaction not confirmed&quot;);

        transaction.numConfirmations -= 1;
        isConfirmed[_txIndex][msg.sender] = false;

        emit RevokingConfirmation(msg.sender, _txIndex);
    }
    
    function getOwners() public view returns (address[] memory) {
        return owners;
    }
    function getTransactionCount() public view returns (uint) {
        return transactions.length;
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span>

<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> >=0.7.0 &#x3C;0.9.0;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">MultisigWallet</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">Deposit</span> (<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> sender,<span class="hljs-keyword">uint</span> amount,<span class="hljs-keyword">uint</span> balance</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">SubmitingTransaction</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> owner, <span class="hljs-keyword">uint</span> <span class="hljs-keyword">indexed</span> txIndex, <span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> to, <span class="hljs-keyword">uint</span> value, <span class="hljs-keyword">bytes</span> data</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">ConfirmingTransaction</span>(<span class="hljs-params"> <span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> owner, <span class="hljs-keyword">uint</span> <span class="hljs-keyword">indexed</span> txIndex</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">RevokingConfirmation</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> owner, <span class="hljs-keyword">uint</span> <span class="hljs-keyword">indexed</span> txIndex</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">ExecutingTransaction</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> owner, <span class="hljs-keyword">uint</span> <span class="hljs-keyword">indexed</span> txIndex</span>)</span>;

    <span class="hljs-comment">//State Variables.</span>
    <span class="hljs-keyword">address</span>[] <span class="hljs-keyword">public</span> owners;
    <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">bool</span>) <span class="hljs-keyword">public</span> isOwner;
    <span class="hljs-keyword">uint</span> <span class="hljs-keyword">public</span> numConfirmationsRequired;

    <span class="hljs-keyword">struct</span> <span class="hljs-title">Transaction</span> {
        <span class="hljs-keyword">address</span> to;
        <span class="hljs-keyword">uint</span> value;
        <span class="hljs-keyword">bytes</span> data;
        <span class="hljs-keyword">bool</span> executed;
        <span class="hljs-keyword">uint</span> numConfirmations;
    }
    Transaction [] <span class="hljs-keyword">public</span> transactions;

    <span class="hljs-comment">// mapping from tx index => owner => bool</span>
    <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">uint</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">bool</span>)) <span class="hljs-keyword">public</span> isConfirmed;

    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> [] <span class="hljs-keyword">memory</span> _owners, <span class="hljs-keyword">uint</span> _numConfirmationsRequired</span>)  </span>{
        <span class="hljs-built_in">require</span>(_owners.<span class="hljs-built_in">length</span> <span class="hljs-operator">></span> <span class="hljs-number">0</span>,<span class="hljs-string">"Owners Required"</span>);
        <span class="hljs-built_in">require</span>(_numConfirmationsRequired <span class="hljs-operator">></span> <span class="hljs-number">0</span> <span class="hljs-operator">&#x26;</span><span class="hljs-operator">&#x26;</span> _numConfirmationsRequired <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">=</span> _owners.<span class="hljs-built_in">length</span>, <span class="hljs-string">"Invalid number of required Confirmations"</span>);

        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">uint</span> i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> _owners.<span class="hljs-built_in">length</span>; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>){
            <span class="hljs-keyword">address</span> owner <span class="hljs-operator">=</span> _owners[i];

            <span class="hljs-built_in">require</span>(owner <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>), <span class="hljs-string">"invalid Owner"</span>);
            <span class="hljs-built_in">require</span>(<span class="hljs-operator">!</span>isOwner[owner], <span class="hljs-string">"Owner is not unique"</span>);

            isOwner[owner] <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;
            owners.<span class="hljs-built_in">push</span>(owner);
        }

        numConfirmationsRequired <span class="hljs-operator">=</span> _numConfirmationsRequired;
    }

    <span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">onlyOwner</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">require</span>(isOwner[<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>], <span class="hljs-string">"Not Owner"</span>);
        <span class="hljs-keyword">_</span>;
    }
    <span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">txExists</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> _txIndex</span>) </span>{
        <span class="hljs-built_in">require</span>(_txIndex <span class="hljs-operator">&#x3C;</span> transactions.<span class="hljs-built_in">length</span>, <span class="hljs-string">"Transaction does not exist"</span>);
        <span class="hljs-keyword">_</span>;
    }
    <span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">notExecuted</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> _txIndex</span>) </span>{
        <span class="hljs-built_in">require</span>(<span class="hljs-operator">!</span>transactions[_txIndex].executed, <span class="hljs-string">"Transactions already executed"</span>);
        <span class="hljs-keyword">_</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">notconfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> _txIndex</span>)</span>{
        <span class="hljs-built_in">require</span>(<span class="hljs-operator">!</span>isConfirmed[_txIndex][<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>], <span class="hljs-string">"tx already confirmed"</span>);
        <span class="hljs-keyword">_</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">receive</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
        <span class="hljs-keyword">emit</span> Deposit(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>, <span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>).<span class="hljs-built_in">balance</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deposit</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
        <span class="hljs-keyword">emit</span> Deposit (<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>,<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>,<span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>).<span class="hljs-built_in">balance</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">submitTransaction</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _to, <span class="hljs-keyword">uint</span> _value, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> _data</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">onlyOwner</span> </span>{

        <span class="hljs-keyword">uint</span> txIndex <span class="hljs-operator">=</span> transactions.<span class="hljs-built_in">length</span>;
        transactions.<span class="hljs-built_in">push</span>(Transaction({
            to: _to,
            <span class="hljs-built_in">value</span>: _value,
            data: _data,
            executed: <span class="hljs-literal">false</span>,
            numConfirmations: <span class="hljs-number">0</span>
        }));
        <span class="hljs-keyword">emit</span> SubmitingTransaction(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, txIndex, _to, _value, _data);
    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">confirmTransaction</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> _txIndex</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">onlyOwner</span> <span class="hljs-title">txExists</span>(<span class="hljs-params">_txIndex</span>) <span class="hljs-title">notExecuted</span>(<span class="hljs-params">_txIndex</span>) <span class="hljs-title">notconfirmed</span>(<span class="hljs-params">_txIndex</span>)</span>{

        Transaction <span class="hljs-keyword">storage</span> transaction <span class="hljs-operator">=</span> transactions[_txIndex];
        isConfirmed[_txIndex][<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>] <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;
        transaction.numConfirmations <span class="hljs-operator">+</span><span class="hljs-operator">=</span> <span class="hljs-number">1</span>;

        <span class="hljs-keyword">emit</span> ConfirmingTransaction( <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, _txIndex);
    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">executeTransaction</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> _txIndex</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">onlyOwner</span> <span class="hljs-title">txExists</span>(<span class="hljs-params">_txIndex</span>) <span class="hljs-title">notExecuted</span>(<span class="hljs-params">_txIndex</span>) </span>{

        Transaction <span class="hljs-keyword">storage</span> transaction <span class="hljs-operator">=</span> transactions[_txIndex];
        <span class="hljs-built_in">require</span>(transaction.numConfirmations <span class="hljs-operator">></span><span class="hljs-operator">=</span> numConfirmationsRequired,<span class="hljs-string">"Cannot Execute Transaction"</span>);

        transaction.executed <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;
        (<span class="hljs-keyword">bool</span> success,) <span class="hljs-operator">=</span> transaction.to.<span class="hljs-built_in">call</span>{<span class="hljs-built_in">value</span>: transaction.<span class="hljs-built_in">value</span>}(transaction.data);
        <span class="hljs-built_in">require</span>(success, <span class="hljs-string">"tx failed"</span>);

        <span class="hljs-keyword">emit</span> ExecutingTransaction(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, _txIndex);

    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">revokeConfirmation</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> _txIndex</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">onlyOwner</span> <span class="hljs-title">txExists</span>(<span class="hljs-params">_txIndex</span>) <span class="hljs-title">notExecuted</span>(<span class="hljs-params">_txIndex</span>)</span>{

        Transaction <span class="hljs-keyword">storage</span> transaction <span class="hljs-operator">=</span> transactions [_txIndex];
        <span class="hljs-built_in">require</span>(isConfirmed[_txIndex][<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>], <span class="hljs-string">"Transaction not confirmed"</span>);

        transaction.numConfirmations <span class="hljs-operator">-</span><span class="hljs-operator">=</span> <span class="hljs-number">1</span>;
        isConfirmed[_txIndex][<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>] <span class="hljs-operator">=</span> <span class="hljs-literal">false</span>;

        <span class="hljs-keyword">emit</span> RevokingConfirmation(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, _txIndex);
    }
    
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getOwners</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">address</span>[] <span class="hljs-keyword">memory</span></span>) </span>{
        <span class="hljs-keyword">return</span> owners;
    }
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTransactionCount</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>) </span>{
        <span class="hljs-keyword">return</span> transactions.<span class="hljs-built_in">length</span>;
    }
}
</code></pre>]]></content:encoded>
            <author>gachengoh@newsletter.paragraph.com (gachengoh)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/1f2d48d2ffc97b960518076150ceaed93bda7d7c046d90bd6ae9ba8d5faece37.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>