Заблокировать учетную запись в разрешенной среде блокчейна

Мы разрабатываем защищенную блокчейн-среду с помощью Ethermint. Компании должны подать заявку на присоединение к среде блокчейна, мы создаем и предоставляем им их учетную запись Ethereum.

Одна из основных проблем заключается в том, как удалить или заблокировать учетную запись из среды, если выяснится, что эта компания ведет себя нехорошо.

Мы думали о том, чтобы пометить контракт организации или уничтожить его, но тогда вам придется поместить модификатор почти в каждый метод, И они все еще смогут совершать транзакции со своей учетной записью Ethereum.

Я не уверен, что даже возможно заблокировать такую ​​учетную запись из разрешенной среды блокчейна, потому что, ну, это то, что касается децентрализации, очевидно :-) Но, возможно, здесь есть обходной путь или «шаблон».

Ответы (1)

На самом деле очень легко сделать.

Эта функция представляет собой единственную запись для изменения балансов в Ethereum ( core/state_transition.go):

// TransitionDb will transition the state by applying the current message and
// returning the result including the the used gas. It returns an error if it
// failed. An error indicates a consensus issue.
func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) {
    if err = st.preCheck(); err != nil {
        return
    }
    msg := st.msg
    sender := vm.AccountRef(msg.From())
    homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber)
    contractCreation := msg.To() == nil

    // Pay intrinsic gas
    gas, err := IntrinsicGas(st.data, contractCreation, homestead)
    if err != nil {
        return nil, 0, false, err
    }
    if err = st.useGas(gas); err != nil {
        return nil, 0, false, err
    }

    var (
        evm = st.evm
        // vm errors do not effect consensus and are therefor
        // not assigned to err, except for insufficient balance
        // error.
        vmerr error
    )
    if contractCreation {
        ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value)
    } else {
        // Increment the nonce for the next transaction
        st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
        ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value)
    }
    if vmerr != nil {
        log.Debug("VM returned with error", "err", vmerr)
        // The only possible consensus-error would be if there wasn't
        // sufficient balance to make the transfer happen. The first
        // balance transfer may never fail.
        if vmerr == vm.ErrInsufficientBalance {
            return nil, 0, false, vmerr
        }
    }
    st.refundGas()
    st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))

    return ret, st.gasUsed(), vmerr != nil, err
}

Вы должны сделать что-то вроде этого:

func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) {
    if err = st.preCheck(); err != nil {
        return
    }
    msg := st.msg
    sender := vm.AccountRef(msg.From())
    homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber)
    contractCreation := msg.To() == nil

    // here is where your custom code goes:

    errAccessDenied:=errors.New("Company isn't playing nice")
    blacklisted_address,exists:=blacklists[sender]
    if exists {
        return ret,0,false, errAccessDenied
    }
    blacklisted_address,exists=blaclists[st.to()]
    if exists {
        return ret,0,false,errAccessDenied
    }
    // here is where your custom code ends   

    // Pay intrinsic gas
    gas, err := IntrinsicGas(st.data, contractCreation, homestead)
    if err != nil {
        return nil, 0, false, err
    }
    if err = st.useGas(gas); err != nil {
        return nil, 0, false, err
    }

    var (
        evm = st.evm
        // vm errors do not effect consensus and are therefor
        // not assigned to err, except for insufficient balance
        // error.
        vmerr error
    )

    if contractCreation {
        ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value)
    } else {
        // Increment the nonce for the next transaction
        st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
        ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value)
    }
    if vmerr != nil {
        log.Debug("VM returned with error", "err", vmerr)
        // The only possible consensus-error would be if there wasn't
        // sufficient balance to make the transfer happen. The first
        // balance transfer may never fail.
        if vmerr == vm.ErrInsufficientBalance {
            return nil, 0, false, vmerr
        }
    }
    st.refundGas()
    st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))

    return ret, st.gasUsed(), vmerr != nil, err
}

Конечно, это не проверенный код, но вы поняли. Также вы должны включить функцию распределения списка компаний, которые не ладят между узлами. Хэш черного списка должен быть включен в заголовок блока (types.Header)