# EPF - Week 7 Since [last week](https://hackmd.io/@2xic/Bkbt8Grvle) we went from having 3 opcodes implemented to now having [22 opcodes implemented](https://github.com/2xic/erigon-risc-v-executable-proof-sourcing/pull/2). Most of these opcodes are still simple stack opcodes, we also got a initial version of Int256/U256 support working and did some exploration of external state opcodes. ## Opcodes status ### External state opcodes As mentioned in last weeks update we didn't expect to get to implementing these in this week and that turned out to be correct. We were able to do some initial research, I'm somewhat debating if I want to just inject the external state directly into the data section as originally planned or if I want to see if there is some way to also preserve some of the semantics of the opcode. For instance that `SLOAD` /`CALLDATALOAD`/etc are somehow able to request the state from the db by communicating with the host. This is something I'll need to look more into next week. One concern is that it won't be possible without recompiling the entire statedb into RISC-V which is the opposite of what this project is trying to do. ### Status on getting hello world working As mentioned last week, we probably wouldn't get to the state modifying ones which turned out to be almost correct (see previous section). Update version of the [table from last week](https://hackmd.io/@2xic/Bkbt8Grvle#Opcodes-to-implement-for-next-week) | OPCODE | COUNT | IMPLEMENTED | | ------------ | ----- | ----------- | | PUSH1 | 36 | X | | PUSH0 | 18 | X | | JUMPI | 16 | X | | DUP1 | 9 | X | | JUMPDEST | 8 | X | | DUP2 | 7 | X | | MSTORE | 6 | X | | ADD | 6 | X | | SWAP1 | 5 | X | | REVERT | 5 | | | PUSH4 | 5 | X | | NOT | 5 | | | CALLVALUE | 5 | | | CALLDATASIZE | 5 | | | SLT | 4 | X | | SLOAD | 4 | | | EQ | 4 | X | | RETURN | 3 | | | STOP | 2 | X | | SSTORE | 2 | | | GT | 2 | X | | SWAP2 | 1 | X | | SHR | 1 | X | | SHL | 1 | X | | POP | 1 | X | | MLOAD | 1 | X | | LT | 1 | X | | ISZERO | 1 | X | | INVALID | 1 | | | DUP3 | 1 | X | | CODECOPY | 1 | | | CALLDATALOAD | 1 | | ## Int256/U256 support At the end of last week I learned that OpenVM had a [bitint extension](https://github.com/openvm-org/openvm/blob/ca36de3803213da664b03d111801ab903d55e360/docs/specs/RISCV.md#bigint-extension), great, I thought as it would help me work around the 256 bit issues easily as I can just use the opcodes directly. This didn't turn out to be as easy as I first thought as the compilation pipeline of OpenVM is a bit more involved. That said, I was able to get it working by using the rust crate [openvm-bigint-guest](https://github.com/openvm-org/openvm/blob/v1.2.0/extensions/bigint/guest/Cargo.toml) they are providing and exposing it with wrapper functions. It can be done like this ```rust #[no_mangle] extern "C" fn u256_from_words_to_ptr(words: *const u32, dest: *mut U256) { unsafe { let word_slice = core::slice::from_raw_parts(words, 8); let mut bytes = [0u8; 32]; // Convert 8 u32 words to 32 bytes (little-endian) for (i, &word) in word_slice.iter().enumerate() { let word_bytes = word.to_le_bytes(); bytes[i * 4..(i + 1) * 4].copy_from_slice(&word_bytes); } let result = U256::from_le_bytes(bytes); ptr::write(dest, result); } } ``` Then called into like (`input_uint256_words` and `output_uint256` would be scratch space inside the program) ```assembly la a0, input_uint256_words la a1, output_uint256 call u256_from_words_to_ptr ``` **Haven't checked yet if this actually uses the optimized opcodes when it reaches the zkVM, but want to do that in one of the coming weeks.** *One caveat of not being able to use the opcodes directly is extra overhead, so I'll also want to re-explore using the extended ISA opcodes later in the project. Using the wrapper does unblock us however.* *P.S: this change is still on a WIP branch, but I'll try to upstream it next week* ## Next week For next week I hope to have a plan for handling the external state. We should also get some of the state opcodes implemented and be more or less ready for executing the hello world contract.