I am new to Ethereum, I am developing a voting app following this example:
https://github.com/dappuniversity/election
I want to create a new account and give private keys to users so they can cast their votes using their private keys. When I am switching accounts from Metamask, [msg.sender] account address also changes. I want to switch the account without Metamask so [msg.sender] can also change the account address. How can I achieve it? I don't want to switch the account address from Metamask.
function vote (uint _candidateId) public {
require(!voters[msg.sender]);
require(_candidateId > 0 && _candidateId <= candidatesCount);
// record that voter has already voted
voters[msg.sender] = true;
// update candidate voteCount
candidates[_candidateId].voteCount ++;
}
I am using Truffle v5.1.4, Solidity v0.5.12, Web3.js v1.2.1, and Ganache
for example:
You will have to do it from the Dapp. You will have to use the private key to sign the operation of your vote. See this link:
https://ethereum.stackexchange.com/questions/25839/how-to-make-transactions-using-private-key-in-web3
Was very helpful to me when I had to use execute operations in name of other addresses having their private keys.
Related
I am trying to build a smart contract application similar to mainstream betting. I would love to know the best way to store user (betters) stakes for a betting event.
The smart contract has an Event contract that any EOA can create.
Each event can have multiple markets.
Let's say an event can be a football match between Manchester United and Chelsea.
A market with this instance can be "double chance" or "3way";
Each market can have multiple pools.
Pools with this instance can be "1X or 12 or X2" or "1 or X or 2" respectively.
Users can place bets on these pools. On placing bets, A Bet contract is created in the pool contract.
Here is an example of the Bet contract
contract Bets is IWeb3BetsBetsV1 {
address public better;
address public eventAddress;
address public marketAddress;
address public poolAddress;
uint256 public stake;
modifier onlyEventOwner {
IWeb3BetsEventV1 betEvent = IWeb3BetsEventV1(eventAddress);
require(tx.origin == betEvent.getEventOwner(), "Only bet owners can apply this function");
_;
}
modifier onlyBetter {
require(tx.origin == better, "Only event better can call this function");
_;
}
constructor(
address _eventAddress,
address _marketAddress,
address _poolAddress,
uint256 _stake,
address _better
) {
eventAddress = _eventAddress;
marketAddress = _marketAddress;
stake = _stake;
better = _better;
poolAddress = _poolAddress;
}
function getBetStake() override external view returns (uint256) {
return stake;
}
function getBetter() override external view returns (address) {
return better;
}
function getBetPoolAddress() override external view returns (address) {
return poolAddress;
}
function getBetMarketAddress() override external view returns (address) {
return marketAddress;
}
function getBetEventAddress() override external view returns (address) {
return eventAddress;
}
function withdraw() override external payable onlyBetter {
require(address(this).balance > 0, "This bet has no funds");
IWeb3BetsEventV1 eventV1 = IWeb3BetsEventV1(eventAddress);
uint status = eventV1.getEventStatus();
// its not equal to pending or started
if (status== 0 && status ==1){
revert("An event must be cancelled or ended to withdraw funds and earnings");
}
IWeb3BetsMarketV1 marketV1 = IWeb3BetsMarketV1(marketAddress);
bool isWinningPool = marketV1.isWinningPool(poolAddress);
if (!isWinningPool){
revert("You lost this bet");
}
payable(msg.sender).transfer(address(this).balance);
}
fallback() payable external {}
receive() payable external {}
}
I have two options for storing user's bets,
Transferring the user's stake (msg.value) to the market contract.
Transferring the user's stake to the Bet contract.
I am looking for a better and cost-efficient way to store the user's bet stake.
The contract algorithm for option one gets all addresses of the winning pool in the market and transfers their respective bet earnings to the Bet's contract getBetterAddress() address. This also only runs when the event creator ends the contract and sets the winning pool for each market. But I have doubts when the betters reaches say one thousand. I will have to loop through them and send their earnings to them respectively.
I would really love some help on which could be the best approach
The second option is indeed better. Wherever you can avoid iterating through something, do it.
In fact, you shouldn't iterate through users at all. You should use a Pull over Push design: https://fravoll.github.io/solidity-patterns/pull_over_push.html
function deposit(address payable referrer) public payable whenNotPaused
{
}
In my case I need insert address, otherway I will get:
"{"reason":"invalid address","code":"INVALID_ARGUMENT","arg":"","coderType":"address","value":""}"
Is there any way if user not enter any text, can add my own text in Solidity?
This box is marked as required, but I want as not required.
I used shasta.tronscan.org .
In my JS no problem, but if user use directly then need to use from code Solidity.
Thanks
I'm trying to understand your question. Are you want to use default parameters?
Well, Solidity does not support default parameters, but it is on their roadmap (see https://github.com/ethereum/solidity/issues/232). To work around this, just use function overloading:
function deposit() public payable whenNotPaused{
address referrer = 0x..... // use your default parameter.
//Your code
}
function deposit(address payable referrer) public payable whenNotPaused {
// Your Code
}
I'm currently working on ethereum platform(node.js and solidity). My question is how do I trigger an event in solidity(contract) using node.js?
Here is a sample event definition at smart contract:
contract Coin {
//Your smart contract properties...
// Sample event definition: use 'event' keyword and define the parameters
event Sent(address from, address to, uint amount);
function send(address receiver, uint amount) public {
//Some code for your intended logic...
//Call the event that will fire at browser (client-side)
emit Sent(msg.sender, receiver, amount);
}
}
The line event Sent(address from, address to, uint amount); declares a so-called “event” which is fired in the last line of the function send. User interfaces (as well as server applications of course) can listen for those events being fired on the blockchain without much cost. As soon as it is fired, the listener will also receive the arguments from, to and amount, which makes it easy to track transactions. In order to listen for this event, you would use.
Javascript code that will catch the event and write some message in the browser console:
Coin.Sent().watch({}, '', function(error, result) {
if (!error) {
console.log("Coin transfer: " + result.args.amount +
" coins were sent from " + result.args.from +
" to " + result.args.to + ".");
console.log("Balances now:\n" +
"Sender: " + Coin.balances.call(result.args.from) +
"Receiver: " + Coin.balances.call(result.args.to));
}
})
Ref:
http://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html
Events are triggered from within functions. So, you can trigger one by calling a function that calls an event. Here is more information: Solidity Event Documentation.
So basically you don't trigger the event directly throughout the node.js code.
Let's say you have solidity contract which looks like this:
contract MyContract {
event Deposit(address indexed _from, uint256 _value);
function deposit(uint256 value) public {
...
emit Deposit(msg.sender, value);
...
}
}
In order to trigger the event you have to call the deposit(uint256) function, which would look like this:
const myContract = new web3.eth.Contract(contract_abi, contract_address);
myContract.deposit("1000").send({ from: "0x..." }) // function call
And only if the transaction generated from the function call is successful and you have subscribed to this type of events you will be able to see the emitted event.
On how to subscribe to event
Event is triggered when you call functions of smart contract via web3.
You can just watch events in the node.js to know what happened on-chain.
you can refer this
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.8.0;
contract EventExample {
event DataStored(uint256 val);
uint256 val;
function storeData(uint256 _val) external {
val = _val;
emit DataStored(val);
}
}
Events allow the convenient usage of the EVM logging facilities, which in turn can be used to “call” JavaScript callbacks in the user interface of a dapp, which listen for these events, you can check here for detail
Add event emit to a function and than call that function. You can also use mock contract (only if necessary) in case you just use events for debugging and don't need an event in contract itself. In this case get a return from your contract function into a mock's function and than fire an event there with that return value. In JS you just need to only call mock's function and then read an event.
You'd have to define the event in your smart contract and have it trigger from a function in your smart contract . To trigger it through node you will have to call the function in your smart contract through web3.
I am using axon 2.3.1 , I have one aggregate class
public class MyAggregate extends AbstractAnnotatedAggregateRoot<MBAggregate> {
#AggregateIdentifier
private MyId Id;
private Circle circle;
EventDispatcher a=new EventDispatcher();
public MyAggregate() {
}
#CommandHandler
public MyAggregate(NewCommand command ) {
apply(new SmallEvent(command.getId(), command.getCircle()));
}
#CommandHandler
public MyAggregate( StoreDestinationsCommand command ) {
apply(new BigEvent(command.getId(), command.getCircle()));
}
//And some event handlers like
#EventHandler
public void onSmallEvent(SmallEvent event)
{
//Some logic here
}
#EventHandler
public void onBigEvent(BigEvent event)
{
//Some logic here
}
Now i want these event handlers to be contained in some other class and be called when that event get triggered
public class EventContainer {
private static final long serialVersionUID = -6640657879730853388L;
#EventHandler
public void onSmallEvent(SmallEvent event)
{
//Some logic here
}
#EventHandler
public void onBigEvent(BigEvent event)
{
//Some logic here
}
I tried putting them in another class but those events are not triggered.
Any idea how can i achieve this in AXON.
Thanks,
Short Answer: You need to tell Axon that your EventContainer class can handle events published to an Event Bus.
AnnotationEventListenerAdapter.subscribe(new EventContainer(), eventBus);
Longer Answer:
To achieve what you want to do, taking a step back to understand the building blocks provided by Axon to build a CQRS application would be of help...
Axon Framework is a framework that provides you with the building blocks to build a CQRS application. And a CQRS application, in layman's term is just an architecture that allows you to separate the part of your application that executes actions (write) and the part that display your application state (read).
To do this Axon provide a couple of building blocks.
1) CommandBus
The Command Bus is the component within Axon Framework that provides the mechanism of having commands routed to their respective Command Handlers. For example from your code sample, the #CommandHandler annotation on MyAggregate means that when NewCommand is created, your MyAggregate method would be called. The Command Bus is the component that makes this possible.
2) CommandGateway
Command GateWay is a component that exposes a more friendly API to the CommnadBus. While you are not required to use a Gateway to dispatch Commands, it is generally the easiest option to do so.
3) EventBus
The EventBus handles the dispatching mechanism for events. Much like the Command Bus does for Commands. So when you have apply(new BigEvent(command.getId(), command.getCircle())); which fires a BigEvent it is the Event Bus that is responsibly for making sure the necessary event handler is called. And in your case, the question you are asking is how to have the Event handlers defined in a separate Class and still have Axon be able to route the events to them.
This is quite straight forward. I would assume you are not using Spring and that you are manually setting up the Axon components together by hand and creating the NewCommand that triggers the SmallEvent that you want to handle in EventContainer#onSmallEvent method. A way to get this done may look like this:
public class FireCommandAndCaptureEventInAnotherClass {
public static void main(String[] args) {
// We use the simple Command Bus.
// There are different implementation available. For example axon provides a distributed command bus that can be used to distribute commands over multiple nodes
CommandBus commandBus = new SimpleCommandBus();
// The friendlier API to send commands with
CommandGateway commandGateway = new DefaultCommandGateway(commandBus);
// You may skip this as it may not pertain to your question but since we are using event sourcing, we need a place to store the events. we'll store Events on the FileSystem, in the "events" folder
EventStore eventStore = new FileSystemEventStore(new SimpleEventFileResolver(new File("./events")));
// a Simple Event Bus will do
EventBus eventBus = new SimpleEventBus();
// You may skip this as it may not pertain to your question but since event sourcing is used in this example we need to configure the repository: an event sourcing repository.
EventSourcingRepository<MyAggregate> repository = new EventSourcingRepository<MyAggregate>(MyAggregate.class,
eventStore);
// Sets the event bus to which newly stored events should be published
repository.setEventBus(eventBus);
// Tells Axon that MyAggregate can handle commands
AggregateAnnotationCommandHandler.subscribe(MyAggregate.class, repository, commandBus);
// This is the part you need. With this We register an event listener to be able to handle events published on to an event bus. In this case EventContainer.
AnnotationEventListenerAdapter.subscribe(new EventContainer(), eventBus);
// and let's send some Commands on the CommandBus.
commandGateway.send(id, circle);
}
}
With this setup, the handlers in the EventContainer would be able to react to events triggered from MyAggregate
My app is calling SpeechSynthesizer.SpeakTextAsync multiple time, so most of the text will be add to the queue before spoken. I want to give user the ability to cancel the speech and discard eveyything that's still in the queue.
I tried calling either SpeechSynthesizer.CancelAll or SpeechSynthesizer.Dispose and the app will just crash when either of the methods were called.
I've looked at Cancel speech synthesis in windows phone 8 but since my app add multiple speech to the queue, Task.Cancel doesn't seem to work.
Well, according to the documentation, when you call CancellAll, you're cancelling the Tasks that are executing asynchronously. By contract, this results in an OperationCancelledException being thrown. That means that wherever you call SpeakTextAsync, SpeakSsmlAsync or SpeakSsmlFromUriAsync, you must surround these calls with a try/catch statement to prevent this exception from going uncaught.
private static SpeechSynthesizer synth;
public async static Task<SpeechSynthesizer> SpeechSynth(string dataToSpeak)
{
synth = new SpeechSynthesizer();
IEnumerable<VoiceInformation> englishVoices = from voice in InstalledVoices.All
where voice.Language == "en-US"
&& voice.Gender.Equals(VoiceGender.Female)
select voice;
if (englishVoices.Count() > 0)
{
synth.SetVoice(englishVoices.ElementAt(0));
}
await synth.SpeakTextAsync(dataToSpeak);
return synth;
}
public static void CancelSpeech()
{
synth.CancelAll();
}
Now call the SpeechSynth("Some Data to Speak") where you want, and whenever you want to cancel it, just call CancelSpeech().
Its Done! Enjoy...!