Solidityの数値の明示的な型変換の仕様をRustで試してみた

2021/12/09

Solidity のドキュメントのここ に書いてある内容について、Rust も同じ仕様なのか?などを試してみました。

目次

マイナスの int を uint に変換する

let a:i8 = -3;
println!("a:{}", a as u8);

結果

a:253

Solidity と同じ結果でした。256 を足すと答えが出るみたいになってる。

u32 を u16 に変換する

let b:u32 = 0x12345678;
let c:u16 = b as u16;
println!("b:{}({:#x?}) -> c:{}({:#x?})", b ,b, c, c);

結果

b:305419896(0x12345678) -> c:22136(0x5678)

Solidity と同じ結果でした。

u16 を u32 に変換する

 let d:u16 = 0x1234;
 let e:u32 = d as u32;
 let f:u32 = 0x00001234;
 println!("u16:{:#x?} u32:{:#x?} u32:{:#x?}", d, e, f);

結果

u16:0x1234 u32:0x1234 u32:0x1234

Solidity と同じ結果ってことかなと思いました。器が大きくなっただけなので、値自体は全く変わっていない、と認識しました。

bytes2 から bytes1 にする

Solidity のドキュメントのこれです。 Solidityのドキュメント

int, uint の場合は、容量を減らすと大きい数値がなくなり小さい方が残りますが、byte 列の場合は、大きい方が残ると認識しました。

Rust には、bytes2 とか bytes1 といった型は標準では多分なく、[u8; 2]みたいな u8 型の配列や vector で表すのかなと思います。下記は上記の Solidity の仕様と同じになるように、Rust でやってみたものです。

let g: u32 = 0x04030201;
let h: [u8; 4] = g.to_be_bytes();
let mut i: [u8; 2] = [0; 2];
i.clone_from_slice(&h[..2]);
let k: u16 = u16::from_be_bytes(i);
println!("{}({:#x?}) -> {:?} -> {}({:#x?})", g, g, h, k, k);

結果

67305985(0x4030201) -> [4, 3, 2, 1] -> 1027(0x403)

Rust🦀, Network⚡, PostgreSQL🐘, Unity🎮

Tags

rust  (9)
rocket  (7)
svelte  (5)
c++  (4)
ethereum  (3)
solidity  (3)
vscode  (3)
sqlx  (3)
glfw  (2)
opengl  (2)
nestjs  (2)
graphql  (2)
render  (2)
wsl2  (2)
truffle  (1)
goerli  (1)
geth  (1)
hardhat  (1)
nft  (1)
gui  (1)
tetris  (1)
next.js  (1)
jwt  (1)
nextauth  (1)
node.js  (1)
prisma  (1)
passport  (1)
urql  (1)
codegen  (1)
mdsvex  (1)
markdown  (1)
tmux  (1)
nvim  (1)
axum  (1)
atcoder  (1)
vim  (1)
pacman  (1)
tracing  (1)
Cursor  (1)
VSCode  (1)
PHP  (1)
Laravel  (1)