Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

solidity implementation for ics23 #58

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sol/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.sol linguist-language=Solidity
*.vy linguist-language=Python
lightyear15 marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 6 additions & 0 deletions sol/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__pycache__
.env
.history
.hypothesis/
build/
reports/
3 changes: 3 additions & 0 deletions sol/brownie-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies:
- OpenZeppelin/openzeppelin-contracts@4.2.0
- GNSPS/solidity-bytes-utils@0.8.0
281 changes: 281 additions & 0 deletions sol/contracts/GoogleProtobufAny.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.2;
import "./ProtoBufRuntime.sol";

library GoogleProtobufAny {


//struct definition
struct Data {
string type_url;
bytes value;
}

// Decoder section

/**
* @dev The main decoder for memory
* @param bs The bytes array to be decoded
* @return The decoded struct
*/
function decode(bytes memory bs) internal pure returns (Data memory) {
(Data memory x, ) = _decode(32, bs, bs.length);
return x;
}

/**
* @dev The main decoder for storage
* @param self The in-storage struct
* @param bs The bytes array to be decoded
*/
function decode(Data storage self, bytes memory bs) internal {
(Data memory x, ) = _decode(32, bs, bs.length);
store(x, self);
}
// inner decoder

/**
* @dev The decoder for internal usage
* @param p The offset of bytes array to start decode
* @param bs The bytes array to be decoded
* @param sz The number of bytes expected
* @return The decoded struct
* @return The number of bytes decoded
*/
function _decode(uint256 p, bytes memory bs, uint256 sz)
internal
pure
returns (Data memory, uint)
{
Data memory r;
uint[3] memory counters;
uint256 fieldId;
ProtoBufRuntime.WireType wireType;
uint256 bytesRead;
uint256 offset = p;
uint256 pointer = p;
while (pointer < offset + sz) {
(fieldId, wireType, bytesRead) = ProtoBufRuntime._decode_key(pointer, bs);
pointer += bytesRead;
if (fieldId == 1) {
pointer += _read_type_url(pointer, bs, r, counters);
}
else if (fieldId == 2) {
pointer += _read_value(pointer, bs, r, counters);
}

else {
if (wireType == ProtoBufRuntime.WireType.Fixed64) {
uint256 size;
(, size) = ProtoBufRuntime._decode_fixed64(pointer, bs);
pointer += size;
}
if (wireType == ProtoBufRuntime.WireType.Fixed32) {
uint256 size;
(, size) = ProtoBufRuntime._decode_fixed32(pointer, bs);
pointer += size;
}
if (wireType == ProtoBufRuntime.WireType.Varint) {
uint256 size;
(, size) = ProtoBufRuntime._decode_varint(pointer, bs);
pointer += size;
}
if (wireType == ProtoBufRuntime.WireType.LengthDelim) {
uint256 size;
(, size) = ProtoBufRuntime._decode_lendelim(pointer, bs);
pointer += size;
}
}

}
return (r, sz);
}

// field readers

/**
* @dev The decoder for reading a field
* @param p The offset of bytes array to start decode
* @param bs The bytes array to be decoded
* @param r The in-memory struct
* @param counters The counters for repeated fields
* @return The number of bytes decoded
*/
function _read_type_url(
uint256 p,
bytes memory bs,
Data memory r,
uint[3] memory counters
) internal pure returns (uint) {
/**
* if `r` is NULL, then only counting the number of fields.
*/
(string memory x, uint256 sz) = ProtoBufRuntime._decode_string(p, bs);
if (isNil(r)) {
counters[1] += 1;
} else {
r.type_url = x;
if (counters[1] > 0) counters[1] -= 1;
}
return sz;
}

/**
* @dev The decoder for reading a field
* @param p The offset of bytes array to start decode
* @param bs The bytes array to be decoded
* @param r The in-memory struct
* @param counters The counters for repeated fields
* @return The number of bytes decoded
*/
function _read_value(
uint256 p,
bytes memory bs,
Data memory r,
uint[3] memory counters
) internal pure returns (uint) {
/**
* if `r` is NULL, then only counting the number of fields.
*/
(bytes memory x, uint256 sz) = ProtoBufRuntime._decode_bytes(p, bs);
if (isNil(r)) {
counters[2] += 1;
} else {
r.value = x;
if (counters[2] > 0) counters[2] -= 1;
}
return sz;
}


// Encoder section

/**
* @dev The main encoder for memory
* @param r The struct to be encoded
* @return The encoded byte array
*/
function encode(Data memory r) internal pure returns (bytes memory) {
bytes memory bs = new bytes(_estimate(r));
uint256 sz = _encode(r, 32, bs);
assembly {
mstore(bs, sz)
}
return bs;
}
// inner encoder

/**
* @dev The encoder for internal usage
* @param r The struct to be encoded
* @param p The offset of bytes array to start decode
* @param bs The bytes array to be decoded
* @return The number of bytes encoded
*/
function _encode(Data memory r, uint256 p, bytes memory bs)
internal
pure
returns (uint)
{
uint256 offset = p;
uint256 pointer = p;

pointer += ProtoBufRuntime._encode_key(
1,
ProtoBufRuntime.WireType.LengthDelim,
pointer,
bs
);
pointer += ProtoBufRuntime._encode_string(r.type_url, pointer, bs);
pointer += ProtoBufRuntime._encode_key(
2,
ProtoBufRuntime.WireType.LengthDelim,
pointer,
bs
);
pointer += ProtoBufRuntime._encode_bytes(r.value, pointer, bs);
return pointer - offset;
}
// nested encoder

/**
* @dev The encoder for inner struct
* @param r The struct to be encoded
* @param p The offset of bytes array to start decode
* @param bs The bytes array to be decoded
* @return The number of bytes encoded
*/
function _encode_nested(Data memory r, uint256 p, bytes memory bs)
internal
pure
returns (uint)
{
/**
* First encoded `r` into a temporary array, and encode the actual size used.
* Then copy the temporary array into `bs`.
*/
uint256 offset = p;
uint256 pointer = p;
bytes memory tmp = new bytes(_estimate(r));
uint256 tmpAddr = ProtoBufRuntime.getMemoryAddress(tmp);
uint256 bsAddr = ProtoBufRuntime.getMemoryAddress(bs);
uint256 size = _encode(r, 32, tmp);
pointer += ProtoBufRuntime._encode_varint(size, pointer, bs);
ProtoBufRuntime.copyBytes(tmpAddr + 32, bsAddr + pointer, size);
pointer += size;
delete tmp;
return pointer - offset;
}
// estimator

/**
* @dev The estimator for a struct
* @param r The struct to be encoded
* @return The number of bytes encoded in estimation
*/
function _estimate(
Data memory r
) internal pure returns (uint) {
uint256 e;
e += 1 + ProtoBufRuntime._sz_lendelim(bytes(r.type_url).length);
e += 1 + ProtoBufRuntime._sz_lendelim(r.value.length);
return e;
}

//store function
/**
* @dev Store in-memory struct to storage
* @param input The in-memory struct
* @param output The in-storage struct
*/
function store(Data memory input, Data storage output) internal {
output.type_url = input.type_url;
output.value = input.value;

}



//utility functions
/**
* @dev Return an empty struct
* @return r The empty struct
*/
function nil() internal pure returns (Data memory r) {
assembly {
r := 0
}
}

/**
* @dev Test whether a struct is empty
* @param x The struct to be tested
* @return r True if it is empty
*/
function isNil(Data memory x) internal pure returns (bool r) {
assembly {
r := iszero(x)
}
}
}
//library Any
19 changes: 19 additions & 0 deletions sol/contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

contract Migrations {
address public owner;
uint public last_completed_migration;

modifier restricted() {
if (msg.sender == owner) _;
}

constructor() public {
owner = msg.sender;
}

function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
}
Loading