Logicky Blog

Logickyの開発ブログです

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

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)