function toRlp(bytes memory _value) internal pure returns (bytes memory _bytes) {
        uint _valuePtr;
        uint _rplPtr;
        uint _valueLength = _value.length;

        assembly {
            _valuePtr := add(_value, 0x20)
            _bytes := mload(0x40)                   
            _rplPtr := add(_bytes, 0x20)            
        }

        
        if (_valueLength == 1 && _value[0] <= 0x7f) {
            assembly {
                mstore(_bytes, 1)                   
                mstore(_rplPtr, mload(_valuePtr))  
                mstore(0x40, add(_rplPtr, 1))       
            }
            return;
        }

        
        if (_valueLength <= 55) {
            assembly {
                mstore(_bytes, add(1, _valueLength))            
                mstore8(_rplPtr, add(0x80, _valueLength))       
                mstore(0x40, add(add(_rplPtr, 1), _valueLength)) 
            }

            copy(_valuePtr, _rplPtr + 1, _valueLength);
            return;
        }

        
        uint _lengthSize = uintMinimalSize(_valueLength);

        assembly {
            mstore(_bytes, add(add(1, _lengthSize), _valueLength))  
            mstore8(_rplPtr, add(0xb7, _lengthSize))                
            mstore(add(_rplPtr, 1), mul(_valueLength, exp(256, sub(32, _lengthSize)))) 
            mstore(0x40, add(add(add(_rplPtr, 1), _lengthSize), _valueLength))  
        }

        copy(_valuePtr, _rplPtr + 1 + _lengthSize, _valueLength);
        return;
    }