I am trying to follow the tutorial here : https://goethereumbook.org/block-query/
In his code , he calls the header and then hard codes it into blockNumber.
header, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(header.Number.String()) // 5671744
blockNumber := big.NewInt(5671744)
I have attempted to improve on this and converted the string to int64.
header, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(header.Number.String())
var stringBlockNumber = header.Number.String()
int64BlockNumber, err := strconv.ParseInt(stringBlockNumber, 10, 64)
if err != nil {
log.Fatal(err)
}
blockNumber := big.NewInt(int64BlockNumber)
block, err := client.BlockByNumber(context.Background(), blockNumber)
if err != nil {
log.Fatal(err)
}
This works until in try to add the following line:
fmt.Println(block.Number.Uint64())
I get the following error in the terminal :
./queryBlock.go:41:26: block.Number.Uint64 undefined (type func()
*big.Int has no field or method Uint64)
I would appreciate any pointers on this.
After getting the block by number through client.BlockByNumber, block is of type Block from /github.com/ethereum/go-ethereum/core/types.
Number of Block is a method, which returns a *big.Int instead of being a field of that type. So To retrieve the number, you should call the method, i.e, block.Number().
Related
I would like to list all images from Azure registry via Golang.
What I founded is this: https://github.com/Azure-Samples/azure-sdk-for-go-samples/tree/main/sdk/resourcemanager/containerregistry but nothing from there seems to help me.
Any ideas please?
LE:
I ended up with this code
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/services/preview/containerregistry/runtime/2019-08-15-preview/containerregistry"
"github.com/Azure/go-autorest/autorest"
)
type ACRTokenProvider struct {
accessToken string
}
func (a *ACRTokenProvider) OAuthToken() string {
return a.accessToken
}
func newACRAuthorizer() (*autorest.BearerAuthorizer, error) {
tenantId := "TENANT_ID"
acrService := "servicename.azurecr.io"
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
panic(err)
}
ctx := context.Background()
aadToken, err := cred.GetToken(ctx, policy.TokenRequestOptions{Scopes: []string{"https://management.azure.com/"}})
if err != nil {
panic(err)
}
formData := url.Values{
"grant_type": {"access_token"},
"service": {acrService},
"tenant": {tenantId},
"access_token": {aadToken.Token},
}
jsonResponse, err := http.PostForm(fmt.Sprintf("https://%s/oauth2/exchange", acrService), formData)
if err != nil {
panic(err)
}
var response map[string]interface{}
json.NewDecoder(jsonResponse.Body).Decode(&response)
return autorest.NewBearerAuthorizer(&ACRTokenProvider{accessToken: fmt.Sprint(response["refresh_token"])}), nil
}
func main() {
client := containerregistry.NewRepositoryClient("https://servicename.azurecr.io")
authorizer, err := newACRAuthorizer()
if err != nil {
fmt.Println(err)
}
client.Authorizer = authorizer
// Do what you need to do with client here
attributes, err := client.GetList(context.Background(), "registryName", nil)
if err != nil {
log.Printf("Error while fetching attributes, %v ", err)
}
fmt.Print(attributes)
}
But the response is this
Original Error: autorest/azure: Service returned an error. Status=401 Code="Unknown" Message="Unknown service error" Details=[{"errors":[{"code":"UNAUTHORIZED","detail":[{"Action":"*","Name":"catalog","Type":"registry"}],"message":"authentication required, visit https://aka.ms/acr/authorization for more information."}]}]
What I'm missing?
i'm not sure about the GO SDK, but you can always consume the REST API directly:
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.ContainerRegistry/registries?api-version=2019-05-01
https://learn.microsoft.com/en-us/rest/api/containerregistry/registries/list?tabs=HTTP
I'm trying to monitor a file using the fsnotify packet in golang.
I saw few examples like this and I would like to know if this is the best way of using fsnotify:
package main
import (
"log"
"github.com/howeyc/fsnotify"
)
func main() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
done := make(chan bool)
// Process events
go func() {
for {
select {
case ev := <-watcher.Event:
log.Println("event:", ev)
case err := <-watcher.Error:
log.Println("error:", err)
}
}
}()
err = watcher.Watch("testDir")
if err != nil {
log.Fatal(err)
}
<-done
var get_info := []string
get_info = read_file(path_to_file)
watcher.Close()
}
Basically I'm passing a path where the file is located and geting the resul in a string variable.
Everytime I change the file I would like to read the file and get the result.
I'm not sure if I'm using fsnotify correctly base on that example. Also, I'm not sure where to put the file path in the fsnotify to monitor that file.
You're leveraging fsnotify pretty much correctly, the only change would likely be that you want to utilize the channel to grab events and then use the event to extract the file name that changed. This would allow you to monitor multiple files and also in your example I don't believe you ever pass a value into done for it to properly finish waiting on the channel and read the file contents.
I'm adding a simple sample below that gets rid of the go routine and simply listens for changes on the main thread.
func main() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
panic(err)
}
err = watcher.Add("file.txt")
if err != nil {
panic(err)
}
for {
select {
case ev := <-watcher.Events:
log.Println("event:", ev)
if ev.Op&fsnotify.Write == fsnotify.Write {
contents, err := ioutil.ReadFile(ev.Name)
if err != nil {
// handle error
}
log.Println("modified file:", string(contents))
}
case err := <-watcher.Errors:
log.Println("error:", err)
}
}
}
I want to overwrite some data on a designed excel already with golang.
So I found a module named excelize.
I tried to read and write seeing the document as below.
func main()
f, err := excelize.OpenFile("ab.xlsx")
if err != nil {
fmt.Println(err)
return
}
rows, err := f.GetRows("Sheet1")
for _, row := range rows {
for _, colCell := range row {
fmt.Print(colCell, "\t")
}
fmt.Println()
}
}
I can read data or write excel.
But my goal is I just want to read an excel with cell designed and overwrite just data on it.
How can I make this? Can you give me some advice?
Thank you for reading it.
f, err := excelize.OpenFile("ab.xlsx")
if err != nil {
fmt.Println(err)
return
}
if err := f.SaveAs("Book2.xlsx"); err != nil {
fmt.Println(err)
}
I found the solution. Thank you.
I'm getting an error when I invoke a chaincode function. I've created two adaptations for the function. One uses a regular key, the other a composite key. I thought that using a composite key would solve any MVCC_READ_CONFLICT's since I'm no longer updating the same key.
However I get the error on both functions. Note that both function are contained in the same chaincode. I don't know if that can cause conflicts.
Here's the function with a regular key:
func (*AddTokenCallFunction) Start(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 2 {
s := fmt.Sprintf(ERROR_INCORRECT_AMOUNT_OF_ARGUMENTS, "add-tokens", 2, len(args))
return shim.Error(s)
}
account := args[0]
tokens := args[1]
currentTokensBytes, err := stub.GetState(account)
if err != nil {
s := fmt.Sprintf(ERROR_SYSTEM, err.Error())
return shim.Error(s)
}
currentAmountOfTokens := binary.LittleEndian.Uint64(currentTokensBytes)
tokensToAdd, err := strconv.ParseUint(tokens, 10, 64)
if err != nil {
s := fmt.Sprintf(ERROR_SYSTEM, err.Error())
return shim.Error(s)
}
currentAmountOfTokens += tokensToAdd
tokenBytes, err := UintToBytes(currentAmountOfTokens)
if err != nil {
s := fmt.Sprintf(ERROR_SYSTEM, err.Error())
return shim.Error(s)
}
err = stub.PutState(account, tokenBytes)
if err != nil {
s := fmt.Sprintf(ERROR_SYSTEM, err.Error())
return shim.Error(s)
}
return shim.Success(nil)
}
Here's the same function but with a composite-key:
func (*AddTokenCompositeCallFunction) Start(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) != 2 {
s := fmt.Sprintf(ERROR_INCORRECT_AMOUNT_OF_ARGUMENTS, "add-composite-tokens", 2, len(args))
return shim.Error(s)
}
account := args[0]
tokens := args[1]
// Retrieve info needed for the update procedure
txid := stub.GetTxID()
compositeIndexaccount := "account~tokens~txID"
// Create the composite key that will allow us to query for all deltas on a particular variable
compositeKey, compositeErr := stub.CreateCompositeKey(compositeIndexaccount, []string{account, tokens, txid})
if compositeErr != nil {
return shim.Error(fmt.Sprintf("Could not create a composite key for %s: %s", account, compositeErr.Error()))
}
// Save the composite key index
compositePutErr := stub.PutState(compositeKey, []byte{0x00})
if compositePutErr != nil {
return shim.Error(fmt.Sprintf("Could not put operation for %s in the ledger: %s", account, compositePutErr.Error()))
}
return shim.Success([]byte(fmt.Sprintf("Successfully added %s to %s", tokens, account)))
}
Could someone explain why I'm still getting a MVCC_READ_CONFLICT on the later implementation? What am I doing wrong? I'm benchmarking and sending the same accountID several times. Though I was under the impression that this would not matter when using a composite-key.
Thanks in advance.
I resolved this issue by removing my own implementation and replacing it with the one from the high-throughput sample [ https://github.com/hyperledger/fabric-samples/blob/release/high-throughput/chaincode/high-throughput.go ].
My guess is that I'm doing something in my implementation that Golang does not agree with. Since the implementations are not that different.
I need to use password authenticated scp to download a file from a server. How do I do so using Go? Tried the following code, but it doesn't pass in the password.
package main
import (
"os/exec"
"time"
)
func main() {
password := "password"
cmd := exec.Command("scp", "admin#192.168.1.150:file", "file")
in, err := cmd.StdinPipe()
if err != nil {
panic(err)
}
defer in.Close()
out, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
defer out.Close()
if err = cmd.Run(); err != nil {
panic(err)
}
go func() {
time.Sleep(10 * time.Second)
_, err = in.Write([]byte(password + "\n"))
if err != nil {
panic(err)
}
}()
}
Edit: I ended up using the gexpect (github.com/ThomasRooney/gexpect) library.
package main
import (
"github.com/ThomasRooney/gexpect"
"log"
)
func main() {
child, err := gexpect.Spawn("scp admin#192.168.1.150:file file")
if err != nil {
log.Fatalln(err)
}
child.Expect("password:")
child.SendLine("password")
child.Interact()
child.Close()
}
The answer to this self-answered question might help:
Golang write input and get output from terminal process
at least, he mentions in the answer that he "was able to get ssh access working with a password", which is not mentioned explicitly in the question - that's why you probably didn't find it while searching the site?