![PyPI Now Supports iOS and Android Wheels for Mobile Python Development](https://cdn.sanity.io/images/cgdhsj6q/production/96416c872705517a6a65ad9646ce3e7caef623a0-1024x1024.webp?w=400&fit=max&auto=format)
Security News
PyPI Now Supports iOS and Android Wheels for Mobile Python Development
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
cra-template-solidity
Advanced tools
A Ethereum starter kit for rapid development of the proof of concept solidity app
A Ethereum starter kit for rapid development of the proof of concept solidity app
A starter kit build especially for rapid smart contract development in Remix IDE. Once you wrote your Solidity smart contract in Remix you could easely deploy it into global testnet or local Ganache blockchain by using a UI. After that simple copy and paste smart contract address into params.ts
Create an app from template
yarn create react-app --template cra-template-solidity .
or
npx create-react-app . --template=solidity
Deploy smart contract to Ganache and update config file (also update ABI if you changed it). The path is
~/src/config/params.ts
export const CC_CONTRACT_ADDRESS = /*process.env.REACT_APP_CONTRACT ||*/ '0xec7e48D6Fb993d532B0aA2E0393461680D7ab83f';
export const CC_APP_NAME = 'HashApp';
export { default as CC_CONTRACT_ABI } from "../contract/ABI.json";
MetaMask Connection request
Network ID check
Contract deployment status check by address
Sample todo-list smart contract
Simple config by variable with smart contract address in source code
Solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.7;
contract TodoList {
struct Todo {
uint id;
string content;
address owner;
bool isDeleted;
}
uint256 public pendingTodoId;
mapping (uint256 => Todo) public todoMap;
function todosOfOwner() public view returns (uint256[] memory) {
uint256 todosLength = pendingTodoId;
uint256[] memory ownedTodoDirtyIds = new uint256[](todosLength);
uint256 ownedTodoIdx = 0;
for (uint id = 0; id != todosLength; id++) {
Todo memory todo = todoMap[id];
if (todo.owner == msg.sender && !todo.isDeleted) {
ownedTodoDirtyIds[ownedTodoIdx] = todo.id;
ownedTodoIdx++;
}
}
uint256[] memory ownedTodoIds = new uint256[](ownedTodoIdx);
for (uint id = 0; id != ownedTodoIdx; id++) {
ownedTodoIds[id] = ownedTodoDirtyIds[id];
}
return ownedTodoIds;
}
function addTodo(string memory _content) public {
uint256 currentId = pendingTodoId++;
Todo memory todo;
todo.id = currentId;
todo.content = _content;
todo.owner = msg.sender;
todoMap[currentId] = todo;
}
function removeTodo(uint256 _id) public {
Todo storage todo = todoMap[_id];
require(todo.owner == msg.sender, 'You are not the owner of that todo');
todo.isDeleted = true;
}
}
TypeScript
import { makeAutoObservable, runInAction } from "mobx";
import { inject, singleshot } from "react-declarative";
import {
ethers,
BaseContract
} from "ethers";
import EthersService from "./EthersService";
import { CC_CONTRACT_ADDRESS } from "../../config/params";
import { CC_CONTRACT_ABI } from "../../config/params";
import TYPES from "../types";
type IContract = BaseContract & Record<string, (...args: any[]) => Promise<any>>;
export class ContractService {
private readonly ethersService = inject<EthersService>(TYPES.ethersService);
private _instance: IContract = null as never;
get isContractConnected() {
return !!this._instance;
};
constructor() {
makeAutoObservable(this);
};
getPendingTodoId = async () => Number(await this._instance.pendingTodoId());
getTodoById = async (id: number) => {
const todoItem = await this._instance.todoMap(id);
return {
id: Number(todoItem.id),
content: String(todoItem.content),
owner: String(todoItem.owner),
isDeleted: Boolean(todoItem.isDeleted),
};
};
addTodo = async (content: string) => await this._instance.addTodo(content);
removeTodoById = async (id: number) => await this._instance.removeTodo(id);
todosOfOwner = async () => {
const todoIds: number[] = (await this._instance.todosOfOwner()).map((bigint: any) => Number(bigint));
return await Promise.all(todoIds.map((id) => this.getTodoById(id)));
};
todosOfEveryone = async () => {
const pendingId = await this.getPendingTodoId();
const totalIds = [...Array(pendingId).keys()];
return await Promise.all(totalIds.map((id) => this.getTodoById(id)));
};
prefetch = singleshot(async () => {
console.log("ContractService prefetch started");
try {
const deployedCode = await this.ethersService.getCode(CC_CONTRACT_ADDRESS);
if (deployedCode === '0x') {
throw new Error('ContractService contract not deployed');
}
const instance = new ethers.Contract(
CC_CONTRACT_ADDRESS,
CC_CONTRACT_ABI,
this.ethersService.getSigner(),
) as IContract;
runInAction(() => this._instance = instance);
} catch (e) {
console.warn('ContractService prefetch failed', e);
}
});
}
This starter kit is build on top of react-declarative npm package. I think you are going to like the way of reactive programming in this app and you will want bring it to other projects which may not require web3 technologies. So check the github repo and seek for other guides
FAQs
A Ethereum starter kit for rapid development of the proof of concept solidity app
We found that cra-template-solidity demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.